/// <summary> /// Tính toán thời gian làm việc thực tế của nhân viên. /// </summary> /// <param name="profile"></param> /// <param name="listWorkDay"></param> /// <param name="listAllShiftItem"></param> /// <param name="listRosterByProfile"></param> /// <param name="listPregnancy"></param> /// <param name="gradeByProfile"></param> /// <returns></returns> public static List<WorkDay> ComputeWorkDays(Hre_Profile profile, List<Att_Workday> listInOut, List<Cat_ShiftItem> listAllShiftItem, List<Att_Roster> listRosterByProfile, List<Att_Pregnancy> listPregnancy, Cat_GradeAttendance gradeCfgByProfile, string userLogin) { List<WorkDay> result = new List<WorkDay>(); if (profile != null && listInOut != null && listInOut.Count() > 0) { listInOut = listInOut.OrderBy(inout => inout.WorkDate).ThenBy(inout => inout.InTime1).ToList(); List<DateTime> listWorkDate = listInOut.Select(d => d.WorkDate.Date).Distinct().OrderBy(d => d).ToList(); if (listWorkDate != null && listWorkDate.Count() > 0) { Dictionary<DateTime, Cat_OrgStructure> listOrgStructure = Att_AttendanceLib.GetDailyLines(profile, listRosterByProfile, listWorkDate.FirstOrDefault(), listWorkDate.LastOrDefault()); foreach (DateTime workDate in listWorkDate) { Cat_OrgStructure orgLine = null; if (listOrgStructure.ContainsKey(workDate)) { //luôn luôn tồn tại 1 line orgLine = listOrgStructure[workDate]; } List<Att_Workday> listInOutByWorkDate = listInOut.Where(io => io.WorkDate.Date == workDate).ToList(); if (listInOutByWorkDate != null && listInOutByWorkDate.Count() > 0) { Att_Pregnancy pregnancyByWorkDay = listPregnancy.Where(d => d.DateStart != null && d.DateEnd != null && d.DateStart.Value <= workDate && d.DateEnd >= workDate).FirstOrDefault(); List<IGrouping<Cat_Shift, Att_Workday>> listInOutGroup = listInOutByWorkDate.Where(d => d.Cat_Shift != null).GroupBy(d => d.Cat_Shift).ToList(); foreach (IGrouping<Cat_Shift, Att_Workday> inOutGroup in listInOutGroup) { List<Cat_ShiftItem> listShiftItem = listAllShiftItem.Where(it => it.ShiftID == inOutGroup.Key.ID).ToList(); WorkDay workDayItem = CreateWorkDay(profile, inOutGroup.ToList(), orgLine, inOutGroup.Key, listShiftItem, pregnancyByWorkDay, gradeCfgByProfile, userLogin); if (workDayItem != null) { result.Add(workDayItem); } } } } } } return result; }
/// <summary> /// Lay table roster Key: Date, Value : Shift /// </summary> /// <param name="profile"></param> /// <param name="rosterCfgPro"></param> /// <param name="lstHistoryPro"></param> /// <param name="gradeCfg"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="lstRosterGroup">Ds RosterGroup</param> /// <param name="lstRosterTypeGroup">Ds Roster loai E_ROSTERGROUP</param> /// <returns></returns> public static Hashtable GetRosterTable(Hre_Profile profile , List<Att_Roster> rosterCfgPro , List<Hre_WorkHistory> lstHistoryPro , Cat_GradeAttendance gradeCfg , DateTime from, DateTime to, List<Att_RosterGroup> lstRosterGroup, List<Att_Roster> lstRosterTypeGroup) { rosterCfgPro = rosterCfgPro.Where(s => s.ProfileID == profile.ID).ToList(); Hashtable res = new Hashtable(); from = from.Date; to = to.Date; //LamLe : 20120809 - #0014556 - Chi lay nhung roster o trang thai Approved String statusApproved = RosterStatus.E_APPROVED.ToString(); List<Att_Roster> rosterApproved = rosterCfgPro.Where(ros => ros.Status == statusApproved || String.IsNullOrEmpty(ros.Status)).ToList(); List<Att_Roster> lstRosterTypeGroup_ByProfile = lstRosterTypeGroup.Where(m => m.ProfileID == profile.ID).ToList(); //LamLe - 20120803 - Lay ca lam viec trong phong ban. if (lstHistoryPro != null && gradeCfg != null && gradeCfg.RosterType == GradeRosterType.E_ISROSTER_ORG.ToString()) { res = GetRosterOrgTable(profile, lstHistoryPro, from, to); } if (rosterApproved != null) //LamLe - 20120803 - Lay ca lam viec dua vao roster { foreach (Att_Roster roster in rosterApproved) { try { if (RosterType.E_DEFAULT.ToString() != roster.Type) continue; DateTime start = from; if (roster.DateStart != null && roster.DateStart > start) start = roster.DateStart; DateTime end = to; if (roster.DateEnd != null && roster.DateEnd < end) end = roster.DateEnd; for (DateTime idx = start; idx <= end; idx = idx.AddDays(1)) { ArrayList arr = new ArrayList(); if (idx.DayOfWeek == DayOfWeek.Monday) arr.Add(roster.Cat_Shift); else if (idx.DayOfWeek == DayOfWeek.Tuesday) arr.Add(roster.Cat_Shift1); else if (idx.DayOfWeek == DayOfWeek.Wednesday) arr.Add(roster.Cat_Shift2); else if (idx.DayOfWeek == DayOfWeek.Thursday) arr.Add(roster.Cat_Shift3); else if (idx.DayOfWeek == DayOfWeek.Friday) arr.Add(roster.Cat_Shift4); else if (idx.DayOfWeek == DayOfWeek.Saturday) arr.Add(roster.Cat_Shift5); else if (idx.DayOfWeek == DayOfWeek.Sunday) arr.Add(roster.Cat_Shift6); if (!res.ContainsKey(idx)) res.Add(idx, arr); } } catch (System.Exception e) { } } #region triet.mai Loai E_ROSTERGROUP loại Đăng ký tăng ca theo nhóm //Logic khá phức tạp //1. Độ ưu tiên thì đứng sau Att_Roster (loại khác Vd: dateOff, ChangeShift) //2. tìm cái roster của từng ngày và kiêm tra cai tên của RosterGroupName >> Chạy qua bảng Att_RosterGroup để tìm Shift string E_ROSTERGROUP = RosterType.E_ROSTERGROUP.ToString(); List<Att_Roster> lstRoster_Type_RosterGroup = lstRosterTypeGroup_ByProfile.Where(m => m.Type == E_ROSTERGROUP).OrderByDescending(m => m.DateStart).ToList(); bool isContinue = true; //Dung de chay nguoc cac roster lay cai moi nhat va ko chay nua => tang toc; foreach (Att_Roster rosterGroup in lstRoster_Type_RosterGroup) { if (isContinue == false) continue; if (rosterGroup.DateStart <= from) { isContinue = false; } DateTime start = from; DateTime end = to; RosterType type = (RosterType)Common.GetEnumValue(typeof(RosterType), rosterGroup.Type); switch (type) { case RosterType.E_ROSTERGROUP: for (DateTime idx = start; idx <= end; idx = idx.AddDays(1)) { bool isExist = res.ContainsKey(idx); ArrayList arr = new ArrayList(); if (isExist) res.Remove(idx); if (string.IsNullOrEmpty(rosterGroup.RosterGroupName)) continue; Att_RosterGroup RosterGroup_Current = lstRosterGroup.Where(m => m.RosterGroupName == rosterGroup.RosterGroupName && m.DateStart <= idx && m.DateEnd >= idx).FirstOrDefault(); if (RosterGroup_Current == null) continue; if (idx.DayOfWeek == DayOfWeek.Monday && RosterGroup_Current.Cat_Shift != null) arr.Add(RosterGroup_Current.Cat_Shift); else if (idx.DayOfWeek == DayOfWeek.Tuesday && RosterGroup_Current.Cat_Shift1 != null) arr.Add(RosterGroup_Current.Cat_Shift1); else if (idx.DayOfWeek == DayOfWeek.Wednesday && RosterGroup_Current.Cat_Shift2 != null) arr.Add(RosterGroup_Current.Cat_Shift2); else if (idx.DayOfWeek == DayOfWeek.Thursday && RosterGroup_Current.Cat_Shift3 != null) arr.Add(RosterGroup_Current.Cat_Shift3); else if (idx.DayOfWeek == DayOfWeek.Friday && RosterGroup_Current.Cat_Shift4 != null) arr.Add(RosterGroup_Current.Cat_Shift4); else if (idx.DayOfWeek == DayOfWeek.Saturday && RosterGroup_Current.Cat_Shift5 != null) arr.Add(RosterGroup_Current.Cat_Shift5); else if (idx.DayOfWeek == DayOfWeek.Sunday && RosterGroup_Current.Cat_Shift6 != null) arr.Add(RosterGroup_Current.Cat_Shift6); if (!res.ContainsKey(idx)) res.Add(idx, arr); } break; default: break; } } #endregion //LamLe - 20121101 - Order theo loai de E_TIME_OFF uu tien sau cung rosterApproved = rosterApproved.OrderBy(rs => rs.Type).ToList(); string E_TIME_OFF = RosterType.E_TIME_OFF.ToString(); string E_CHANGE_SHIFT = RosterType.E_CHANGE_SHIFT.ToString(); List<Att_Roster> lstRoster_Type_TimeOff_ChangeShift = rosterApproved.Where(m => m.Type == E_TIME_OFF || m.Type == E_CHANGE_SHIFT).ToList(); foreach (Att_Roster roster in lstRoster_Type_TimeOff_ChangeShift) { DateTime start = from; if (roster.DateStart != null) start = roster.DateStart; DateTime end = to; if (roster.DateEnd != null) end = roster.DateEnd; RosterType type = (RosterType)Common.GetEnumValue(typeof(RosterType), roster.Type); switch (type) { case RosterType.E_TIME_OFF: for (DateTime idx = start; idx <= end; idx = idx.AddDays(1)) { if (res.ContainsKey(idx)) res.Remove(idx); } break; case RosterType.E_CHANGE_SHIFT: for (DateTime idx = start; idx <= end; idx = idx.AddDays(1)) { bool isExist = res.ContainsKey(idx); ArrayList arr = new ArrayList(); if (isExist) res.Remove(idx); arr.Add(roster.Cat_Shift); res.Add(idx, arr); } break; //case RosterType.E_UNUSUAL: // for (DateTime idx = start; idx <= end; idx = idx.AddDays(1)) // { // bool isExist = res.ContainsKey(idx); // if (!isExist) // res.Add(idx, new ArrayList()); // ((ArrayList)res[idx]).Add(roster.Cat_Shift); // } // break; default: break; } } } return res; }
private static WorkDay CreateWorkDay(Hre_Profile profile, List<Att_Workday> listInOutByWorkDate, Cat_OrgStructure orgLine, Cat_Shift shift, List<Cat_ShiftItem> listShiftItem, Att_Pregnancy pregnancyByWorkDay, Cat_GradeAttendance graCfgPro, string userLogin) { WorkDay result = null; listInOutByWorkDate = listInOutByWorkDate.Where(d => d.InTime1 != null && d.OutTime1 != null).OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).ToList(); if (listInOutByWorkDate != null && listInOutByWorkDate.Count() > 0) { #region Khởi tạo result = new WorkDay(); result.Cat_Shift = shift; result.WorkDuration = 0D; result.WorkDate = listInOutByWorkDate.Select(d => d.WorkDate).FirstOrDefault();//ngày làm việc DateTime timeShiftStart = result.WorkDate.Date.Add(shift.InTime.TimeOfDay);//thời gian bắt đầu của ca làm việc DateTime timeShiftEnd = timeShiftStart.AddHours(shift.CoOut);////thời gian kết thúc của ca làm việc (date + time) double totalTimeShift = timeShiftEnd.Subtract(timeShiftStart).TotalHours; //LamLe - 20121017 - Lay gio lam viec trong grade hay trong Shift double workingStandardHour = graCfgPro.GetWorkHouPerDay(result.WorkDate); //if (shift != null && graCfgPro != null && graCfgPro.WorkHoursType == GradeHoursType.E_SHIFT_HOURS.ToString()) if (shift != null && graCfgPro != null) { workingStandardHour = shift.WorkHours != null ? shift.WorkHours.Value : 0D; } listShiftItem = listShiftItem.Where(sh => sh.ShiftItemType == ShiftItemType.E_SHIFTBREAK.ToString()).OrderBy(p => p.CoFrom).ToList(); Guid? lineID = orgLine != null ? orgLine.ID : profile.OrgStructureID;//LamLe - 20121030 - Xu ly truong hop co Line org trong Roster Cat_ShiftItem shiftItemFlex = listShiftItem.Where(p => p.OrgStructureID == lineID).FirstOrDefault(); double realCoBreakStart = 0D; double realCoBreakEnd = 0D; //Vinhtran: Kiểm tra có giờ nghỉ giữa ca làm việc hay không? if (shift.ShiftBreakType == ShiftBreakType.E_FLEXIBLE.ToString() && totalTimeShift > workingStandardHour && shiftItemFlex != null && shiftItemFlex.CoFrom > 0 && shiftItemFlex.CoTo > shiftItemFlex.CoFrom) { if (!shift.IsBreakAsWork.HasValue || !shift.IsBreakAsWork.Value) { shift.udCoBreakStart = shiftItemFlex.CoFrom; shift.udCoBreakEnd = shiftItemFlex.CoTo; } realCoBreakStart = shiftItemFlex.CoFrom; realCoBreakEnd = shiftItemFlex.CoTo; } else if (shift.CoBreakIn > 0 && shift.CoBreakOut > shift.CoBreakIn) { if (!shift.IsBreakAsWork.HasValue || !shift.IsBreakAsWork.Value) { shift.udCoBreakStart = shift.CoBreakIn; shift.udCoBreakEnd = shift.CoBreakOut; } realCoBreakStart = shift.CoBreakIn; realCoBreakEnd = shift.CoBreakOut; } if (realCoBreakEnd > realCoBreakStart) { totalTimeShift -= realCoBreakEnd - realCoBreakStart; } //Thời gian bắt đầu và kết thúc nghỉ giữa ca - dùng cho tính toán DateTime timeShiftBreakIn = timeShiftStart.AddHours(shift.udCoBreakStart); DateTime timeShiftBreakOut = timeShiftStart.AddHours(shift.udCoBreakEnd); //Khoảng thời gian của nửa ca đầu DateTime firstHalfShiftStart = timeShiftStart; DateTime firstHalfShiftEnd = timeShiftEnd; //Khoảng thời gian của nửa ca sau DateTime lastHalfShiftStart = timeShiftStart; DateTime lastHalfShiftEnd = timeShiftEnd; if (shift.udCoBreakEnd > shift.udCoBreakStart && shift.udCoBreakStart > 0) { firstHalfShiftStart = timeShiftStart; firstHalfShiftEnd = timeShiftBreakIn; lastHalfShiftStart = timeShiftBreakOut; lastHalfShiftEnd = timeShiftEnd; } if (timeShiftBreakIn > timeShiftStart && listInOutByWorkDate.Count() > 1) { //Lần quẹt thẻ vào đầu tiên và lần quẹt thẻ ra cuối cùng của nửa ca đâu if (listInOutByWorkDate.Any(d => d.InTime1 < timeShiftBreakIn)) { result.FirstInTime = listInOutByWorkDate.Where(d => d.InTime1 < timeShiftBreakIn).OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).Select(d => d.InTime1.Value).FirstOrDefault(); result.FirstOutTime = listInOutByWorkDate.Where(d => d.InTime1 < timeShiftBreakIn).OrderBy(d => d.WorkDate).ThenBy(d => d.OutTime1).Select(d => d.OutTime1.Value).LastOrDefault(); } else { result.FirstInTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).Select(d => d.InTime1.Value).FirstOrDefault(); result.FirstOutTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.OutTime1).Select(d => d.OutTime1.Value).FirstOrDefault(); } //Lần quẹt thẻ vào đầu tiên và lần quẹt thẻ ra cuối cùng của nửa ca sau if (listInOutByWorkDate.Any(d => d.OutTime1 > timeShiftBreakOut)) { result.LastInTime = listInOutByWorkDate.Where(d => d.OutTime1 > timeShiftBreakOut).OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).Select(d => d.InTime1.Value).FirstOrDefault(); result.LastOutTime = listInOutByWorkDate.Where(d => d.OutTime1 > timeShiftBreakOut).OrderBy(d => d.WorkDate).ThenBy(d => d.OutTime1).Select(d => d.OutTime1.Value).LastOrDefault(); } else { result.LastInTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).Select(d => d.InTime1.Value).LastOrDefault(); result.LastOutTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.OutTime1).Select(d => d.OutTime1.Value).LastOrDefault(); } } else { //Lần quẹt thẻ vào đầu tiên và lần quẹt thẻ ra cuối cùng của nửa ca đâu result.FirstInTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).Select(d => d.InTime1.Value).FirstOrDefault(); result.FirstOutTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.OutTime1).Select(d => d.OutTime1.Value).LastOrDefault(); //Lần quẹt thẻ vào đầu tiên và lần quẹt thẻ ra cuối cùng của nửa ca sau result.LastInTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).Select(d => d.InTime1.Value).FirstOrDefault(); result.LastOutTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.OutTime1).Select(d => d.OutTime1.Value).LastOrDefault(); } DateTime nightTimeStart = result.WorkDate.Date.AddHours(21); DateTime nightTimeEnd = result.WorkDate.Date.AddDays(1).AddHours(5); double nightDuration = 0D; double firstDuration = 0D; double lastDuration = 0D; if (shift.IsNightShift) { if (shift.NightTimeStart == null || shift.NightTimeEnd == null) { string appConfigName = AppConfig.HRM_ATT_OT_.ToString(); double startHour = 21D; double endHour = 5D; List<object> lstParamSys = new List<object>(); lstParamSys.Add(appConfigName); lstParamSys.Add(null); lstParamSys.Add(null); string status = string.Empty; BaseService baseService = new BaseService(); var lstAppConfig = baseService.GetData<Sys_AllSetting>(lstParamSys, ConstantSql.hrm_sys_sp_get_AllSetting, userLogin, ref status); Sys_AllSetting appConfig13 = lstAppConfig.Where(s => s.IsDelete == null && s.Name == AppConfig.HRM_ATT_OT_NIGHTSHIFTFROM.ToString()).FirstOrDefault(); Sys_AllSetting appConfig14 = lstAppConfig.Where(s => s.IsDelete == null && s.Name == AppConfig.HRM_ATT_OT_NIGHTSHIFTTO.ToString()).FirstOrDefault(); //Sys_AppConfig appConfig = EntityService.Instance.GetEntityList<Sys_AppConfig>(false, // EntityService.Instance.GuidMainContext, Guid.Empty, d => d.Info == appConfigName).FirstOrDefault(); if (lstAppConfig != null && appConfig13 != null && appConfig14 != null) { double.TryParse(appConfig13.Value1, out startHour); double.TryParse(appConfig14.Value1, out endHour); } nightTimeStart = shift.NightTimeStart == null ? result.WorkDate.Date.AddHours(startHour) : result.WorkDate.Date.Add(shift.NightTimeStart.Value.TimeOfDay); nightTimeEnd = shift.NightTimeEnd == null ? result.WorkDate.Date.AddHours(endHour) : result.WorkDate.Date.Add(shift.NightTimeEnd.Value.TimeOfDay); } else { nightTimeStart = result.WorkDate.Date.Add(shift.NightTimeStart.Value.TimeOfDay); nightTimeEnd = result.WorkDate.Date.Add(shift.NightTimeEnd.Value.TimeOfDay); } nightTimeEnd = nightTimeStart > nightTimeEnd ? nightTimeEnd.AddDays(1) : nightTimeEnd; } #endregion foreach (Att_Workday objInOut in listInOutByWorkDate) { if (objInOut.InTime1.HasValue && objInOut.OutTime1.HasValue) { #region Tính work duration DateTime inTime = objInOut.InTime1.Value; DateTime outTime = objInOut.OutTime1.Value; firstDuration += GetIntersectAmountMinutes(inTime, outTime, firstHalfShiftStart, firstHalfShiftEnd); if (timeShiftBreakIn > timeShiftStart) { //Nếu có giờ nghỉ giữa ca lastDuration += GetIntersectAmountMinutes(inTime, outTime, lastHalfShiftStart, lastHalfShiftEnd); } #endregion #region Tính night shift if (shift.IsNightShift) { if (pregnancyByWorkDay != null) { if ((pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_FIRST.ToString() || pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_FIRST_OUT_BEARK.ToString()) && Common.IsOverlap(inTime, outTime, nightTimeStart, nightTimeEnd)) { nightTimeStart = nightTimeStart.AddHours(1); } else if ((pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_LAST.ToString() || pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_LAST_IN_BEARK.ToString()) && Common.IsOverlap(inTime, outTime, nightTimeStart, nightTimeEnd)) { nightTimeEnd = nightTimeEnd.AddHours(-1); } } //Truong hop nghi giua ca nam trong khoang bat dau ca dem if (nightTimeStart >= timeShiftBreakIn && nightTimeStart <= timeShiftBreakOut) { nightDuration += GetIntersectAmountMinutes(inTime, outTime, timeShiftBreakOut, nightTimeEnd); } else if (nightTimeEnd >= timeShiftBreakIn && nightTimeEnd <= timeShiftBreakOut) { nightDuration += GetIntersectAmountMinutes(inTime, outTime, nightTimeStart, timeShiftBreakIn); } else if (nightTimeEnd > timeShiftBreakOut && nightTimeStart < timeShiftBreakIn) { nightDuration += GetIntersectAmountMinutes(inTime, outTime, nightTimeStart, timeShiftBreakIn); nightDuration += GetIntersectAmountMinutes(inTime, outTime, timeShiftBreakOut, nightTimeEnd); } else { nightDuration += GetIntersectAmountMinutes(inTime, outTime, nightTimeStart, nightTimeEnd); } } #endregion } } if (shift.ReduceNightShift != null && shift.ReduceNightShift >= 0) { Int32 reduceNightMinutes = Convert.ToInt32(shift.ReduceNightShift.Value * 60); nightDuration = nightDuration > reduceNightMinutes ? reduceNightMinutes : nightDuration; } nightDuration = nightDuration > 0 ? nightDuration / 60 : 0D; firstDuration = firstDuration > 0 ? firstDuration / 60 : 0D; lastDuration = lastDuration > 0 ? lastDuration / 60 : 0D; //Vinhtran: Tổng thời gian làm việc - tính theo giờ result.WorkDuration = firstDuration + lastDuration; result.NightShiftDuration = nightDuration; result.FirstDuration = firstDuration; result.LastDuration = lastDuration; if (result.WorkDuration > workingStandardHour) { result.WorkDuration = workingStandardHour; } if (result.NightShiftDuration > workingStandardHour) { result.NightShiftDuration = workingStandardHour; } if (shift.IsDoubleShift.Get_Boolean()) { //Vinh.Tran: Xử lý trường hợp ca ghép totalTimeShift = shift.WorkHours.Get_Double(); } //Vinhtran: Tổng thời gian bị đi trễ hoặc về sớm - tính theo giờ result.LateEarlyDuration = totalTimeShift - result.WorkDuration; #region Tính trễ sớm //Có đi trễ hoặc về sớm if (result.LateEarlyDuration > 0) { if (timeShiftBreakIn > timeShiftStart) { if (result.FirstInTime > firstHalfShiftStart && result.FirstInTime < firstHalfShiftEnd) { //thời gian đi trễ nửa ca đầu result.FirstLateDuration = result.FirstInTime.Value.Subtract(firstHalfShiftStart).TotalHours; } if (result.LastInTime > lastHalfShiftStart) { //thời gian đi trễ nửa ca sau result.LastLateDuration = result.LastInTime.Value.Subtract(lastHalfShiftStart).TotalHours; } result.FirstEarlyDuration = firstHalfShiftEnd.Subtract(firstHalfShiftStart).TotalHours - firstDuration - result.FirstLateDuration; result.LastEarlyDuration = lastHalfShiftEnd.Subtract(lastHalfShiftStart).TotalHours - lastDuration - result.LastLateDuration; result.LateDuration = result.FirstLateDuration + result.LastLateDuration; result.EarlyDuration = result.FirstEarlyDuration + result.LastEarlyDuration; } else { if (result.FirstInTime > timeShiftStart) { //thời gian đi trễ nửa ca đầu result.LateDuration = result.FirstInTime.Value.Subtract(timeShiftStart).TotalHours; result.FirstLateDuration = result.LateDuration; result.LastLateDuration = 0; } result.EarlyDuration = timeShiftEnd.Subtract(timeShiftStart).TotalHours - result.WorkDuration - result.LateDuration; result.FirstEarlyDuration = result.EarlyDuration; result.LastEarlyDuration = 0; } if (pregnancyByWorkDay != null) { //Thời gian làm việc lớn nhất có thể xảy ra double maxWorkDuration = totalTimeShift - result.LateEarlyDuration + 1; maxWorkDuration += shift.IsDoubleShift.Get_Boolean() ? 1 : 0;//Ca ghép thì thêm 1 giờ maxWorkDuration = maxWorkDuration > totalTimeShift ? totalTimeShift : maxWorkDuration; if (pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_FIRST.ToString()) { //Chỉ được đi trễ 1 giờ đầu của nửa ca trước, không được về sớm trong nữa ca đầu. result.WorkDuration += result.FirstLateDuration <= 1 ? result.FirstLateDuration : 1; result.FirstLateDuration = result.FirstLateDuration <= 1 ? 0 : result.FirstLateDuration - 1; if (shift.IsDoubleShift.Get_Boolean()) { result.WorkDuration += result.LastLateDuration <= 1 ? result.LastLateDuration : 1; result.LastLateDuration = result.LastLateDuration <= 1 ? 0 : result.LastLateDuration - 1; result.LateDuration = result.LateDuration <= 2 ? 0 : result.LateDuration - 2; } else { result.LateDuration = result.LateDuration <= 1 ? 0 : result.LateDuration - 1; } result.WorkDuration = result.WorkDuration > maxWorkDuration ? maxWorkDuration : result.WorkDuration; } else if (pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_FIRST_OUT_BEARK.ToString()) { //Được đi trễ hoặc về sớm 1 giờ bất kỳ của nửa ca trước, nếu là ca ghép thì được 1 tiếng trễ sớm ở mỗi ca (tổng là 2 tiếng) double firstLatetEarly = timeShiftBreakIn > timeShiftStart ? result.FirstLateDuration + result.FirstEarlyDuration : result.LateDuration + result.EarlyDuration; double lastLatetEarly = (shift.IsDoubleShift.Get_Boolean() && timeShiftBreakIn > timeShiftStart) ? result.LastLateDuration + result.LastEarlyDuration : 0; double totalLatetEarly = firstLatetEarly + lastLatetEarly; if (shift.IsDoubleShift.Get_Boolean()) { result.WorkDuration += totalLatetEarly <= 2 ? totalLatetEarly : 2; result.LateDuration = result.LateDuration <= 2 ? 0 : result.LateDuration - 2; } else { result.WorkDuration += totalLatetEarly <= 1 ? totalLatetEarly : 1; result.LateDuration = result.LateDuration <= 1 ? 0 : result.LateDuration - 1; } if (timeShiftBreakIn > timeShiftStart) { result.FirstLateDuration = result.FirstLateDuration <= 1 ? 0 : result.FirstLateDuration - 1; result.FirstEarlyDuration = firstLatetEarly - result.FirstLateDuration; if (shift.IsDoubleShift.Get_Boolean()) { result.LastLateDuration = result.LastLateDuration <= 1 ? 0 : result.LastLateDuration - 1; result.LastEarlyDuration = lastLatetEarly - result.LastLateDuration; } } result.EarlyDuration = totalLatetEarly - result.LateDuration; } else if (pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_LAST_IN_BEARK.ToString()) { //Được đi trễ hoặc về sớm 1 giờ bất kỳ của nửa ca sau, nếu là ca ghép thì được 1 tiếng trễ sớm ở mỗi ca (tổng là 2 tiếng) double lastLatetEarly = timeShiftBreakIn > timeShiftStart ? result.LastLateDuration + result.LastEarlyDuration : result.LateDuration + result.EarlyDuration; double firstLatetEarly = (shift.IsDoubleShift.Get_Boolean() && timeShiftBreakIn > timeShiftStart) ? result.FirstLateDuration + result.FirstEarlyDuration : 0; double totalLatetEarly = firstLatetEarly + lastLatetEarly; if (shift.IsDoubleShift.Get_Boolean()) { result.WorkDuration += totalLatetEarly <= 2 ? totalLatetEarly : 2; result.LateDuration = result.LateDuration <= 2 ? 0 : result.LateDuration - 2; } else { result.WorkDuration += totalLatetEarly <= 1 ? totalLatetEarly : 1; result.LateDuration = result.LateDuration <= 1 ? 0 : result.LateDuration - 1; } if (timeShiftBreakIn > timeShiftStart) { result.LastLateDuration = result.LastLateDuration <= 1 ? 0 : result.LastLateDuration - 1; result.LastEarlyDuration = lastLatetEarly - result.LastLateDuration; if (shift.IsDoubleShift.Get_Boolean()) { result.FirstLateDuration = result.FirstLateDuration <= 1 ? 0 : result.FirstLateDuration - 1; result.FirstEarlyDuration = firstLatetEarly - result.FirstLateDuration; } } result.EarlyDuration = totalLatetEarly - result.LateDuration; } else if (pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_LAST.ToString()) { //Chỉ được về sớm 1 giờ cuối của nửa ca trước, không được đi trễ trong nữa ca sau. if (timeShiftBreakIn > timeShiftStart) { result.WorkDuration += result.LastEarlyDuration <= 1 ? result.LastEarlyDuration : 1; result.LastEarlyDuration = result.LastEarlyDuration <= 1 ? 0 : result.LastEarlyDuration - 1; if (shift.IsDoubleShift.Get_Boolean()) { result.WorkDuration += result.FirstEarlyDuration <= 1 ? result.FirstEarlyDuration : 1; result.FirstEarlyDuration = result.FirstEarlyDuration <= 1 ? 0 : result.FirstEarlyDuration - 1; } } else { if (shift.IsDoubleShift.Get_Boolean()) { result.WorkDuration += result.EarlyDuration <= 2 ? result.EarlyDuration : 2; } else { result.WorkDuration += result.EarlyDuration <= 1 ? result.EarlyDuration : 1; } } if (shift.IsDoubleShift.Get_Boolean()) { result.EarlyDuration = result.EarlyDuration <= 2 ? 0 : result.EarlyDuration - 2; } else { result.EarlyDuration = result.EarlyDuration <= 1 ? 0 : result.EarlyDuration - 1; } result.WorkDuration = result.WorkDuration > maxWorkDuration ? maxWorkDuration : result.WorkDuration; } } } #endregion //Vinhtran: Tổng thời gian bị đi trễ hoặc về sớm - tính theo phút result.LateDuration = result.LateDuration > 0 ? result.LateDuration * 60 : 0D; result.EarlyDuration = result.EarlyDuration > 0 ? result.EarlyDuration * 60 : 0D; result.FirstLateDuration = result.FirstLateDuration > 0 ? result.FirstLateDuration * 60 : 0D; result.FirstEarlyDuration = result.FirstEarlyDuration > 0 ? result.FirstEarlyDuration * 60 : 0D; result.LastLateDuration = result.LastLateDuration > 0 ? result.LastLateDuration * 60 : 0D; result.LastEarlyDuration = result.LastEarlyDuration > 0 ? result.LastEarlyDuration * 60 : 0D; result.LateEarlyDuration = result.LateEarlyDuration > 0 ? result.LateEarlyDuration * 60 : 0D; //Vinhtran: Tổng thời gian (h) làm ca đêm lớn nhất có thể => làm tròn trễ sớm result.MaxNightDuration = nightTimeEnd.Subtract(nightTimeStart).TotalHours; //Thời gian bắt đầu và kết thúc nghỉ giữa ca - giá trị thực tế result.ShiftBreakInTime = timeShiftStart.AddHours(realCoBreakStart); result.ShiftBreakOutTime = timeShiftStart.AddHours(realCoBreakEnd); //Khoản thời gian làm việc của ca result.ShiftInTime = timeShiftStart; result.ShiftOutTime = timeShiftEnd; if (shift != null && shift.IsNotApplyWorkHoursReal != null && shift.IsNotApplyWorkHoursReal.Value == true) { result.WorkDuration = workingStandardHour - Math.Abs(result.LateDuration / 60) - Math.Abs(result.EarlyDuration / 60); } } return result; }
/// <summary> /// Kiểm tra một ngày có phải là ngày làm việc không? /// Chỉ áp dụng cho trường hợp RosterType = E_ISDEFAULT /// </summary> /// <param name="date"></param> /// <param name="gradeCfg"></param> /// <param name="listDayOff"></param> /// <returns></returns> public static bool IsWorkDay(DateTime date, Cat_GradeAttendance gradeCfg, List<Cat_DayOff> listDayOff) { bool result = false; if (listDayOff == null || !listDayOff.Any(d => d.DateOff.Date == date.Date && d.Type == HolidayType.E_WEEKEND_HLD.ToString())) { if (gradeCfg.RosterType == GradeRosterType.E_ISDEFAULT.ToString()) { if (date.DayOfWeek == DayOfWeek.Monday && gradeCfg.WorkOnMondayID != null) { result = true; } else if (date.DayOfWeek == DayOfWeek.Tuesday && gradeCfg.WorkOnTuesdayID != null) { result = true; } else if (date.DayOfWeek == DayOfWeek.Wednesday && gradeCfg.WorkOnWednesdayID != null) { result = true; } else if (date.DayOfWeek == DayOfWeek.Thursday && gradeCfg.WorkOnThursdayID != null) { result = true; } else if (date.DayOfWeek == DayOfWeek.Friday && gradeCfg.WorkOnFridayID != null) { result = true; } else if (date.DayOfWeek == DayOfWeek.Saturday && gradeCfg.WorkOnSaturdayID != null) { result = true; } else if (date.DayOfWeek == DayOfWeek.Sunday && gradeCfg.WorkOnSundayID != null) { result = true; } } } return result; }
private static double GetRosterStandardWorkDays(Cat_GradeAttendance gradeCfg, List<Cat_Shift> listShift, Dictionary<DateTime, List<Guid?>> listMonthShifts, DateTime dateFrom, DateTime dateTo) { Double result = 0; for (DateTime date = dateFrom.Date; date <= dateTo.Date; date = date.AddDays(1)) { if (listMonthShifts.ContainsKey(date)) { if (listMonthShifts != null && listMonthShifts.Any(d => d.Key.Date == date.Date && d.Value != null)) { var shiftByDate = listMonthShifts.Where(d => d.Key.Date == date.Date && d.Value != null).Select(d => d.Value).FirstOrDefault(); Guid? shiftID1 = Guid.Empty; Guid? shiftID2 = Guid.Empty; if (shiftByDate != null) { if (shiftByDate.Count() > 0) { shiftID1 = shiftByDate[0]; } if (shiftByDate.Count() > 1) { shiftID2 = shiftByDate[1]; } } var shift1 = listShift.Where(p => p.ID == shiftID1).FirstOrDefault(); var shift2 = listShift.Where(p => p.ID == shiftID2).FirstOrDefault(); if (shift1 != null && shift1.WorkHours.HasValue) { result += shift1.WorkHours.Value / shift1.udStandardWorkHours; } if (shift2 != null && shift2.WorkHours.HasValue) { result += shift2.WorkHours.Value / shift2.udStandardWorkHours; } } } } return result; }
/// <summary> /// Tính số ngày phép năm được cộng thêm do thâm niên theo quy định. /// </summary> /// <param name="monthYearEval"></param> /// <param name="dateHire"></param> /// <param name="gradeCfg"></param> /// <returns></returns> public static double GetAnnualBySeniority(DateTime monthYearEval, DateTime? dateHire, Cat_GradeAttendance gradeCfg) { return GetAnnualBySeniority(monthYearEval, DateTime.MinValue, dateHire, gradeCfg); }
/// <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> /// Xac dinh ngay bat dau, ket thuc thang luong dua vao grade /// </summary> /// <param name="grade"></param> /// <param name="monthYear"></param> /// <param name="from"></param> /// <param name="to"></param> private static void GetSalaryDateRange(Cat_GradeAttendance gradeCfg, List<Att_CutOffDuration> lstCutOff, DateTime monthYear , out DateTime from, out DateTime to) { int day = Convert.ToInt32(gradeCfg.SalaryTimeDay); //tan.do: check when day is 0 day = day == 0 ? 1 : day; DateTime _monthYear = new DateTime(monthYear.Year, monthYear.Month, 1); DateTime _from = _monthYear; DateTime _to = _monthYear; if (gradeCfg.IsDurationCutOff != null && gradeCfg.IsDurationCutOff.Value == true && lstCutOff != null && lstCutOff.Count > 0 && !String.IsNullOrEmpty(gradeCfg.DurationType)) { string strDurationType = gradeCfg.DurationType; if (gradeCfg.DurationType == EnumDropDown.DurationType.E_MOTHLY.ToString()) { Att_CutOffDuration cutOffMonth = lstCutOff.Where(cut => cut.DurationType == strDurationType && cut.MonthYear == _monthYear).FirstOrDefault(); if (cutOffMonth!=null) { _from = cutOffMonth.DateStart; _to = cutOffMonth.DateEnd; } } else if (gradeCfg.DurationType == EnumDropDown.DurationType.E_MOTHLY.ToString() || gradeCfg.DurationType == EnumDropDown.DurationType.E_WEEKLY.ToString()) { List<Att_CutOffDuration> lstCutOffMonth = lstCutOff.Where(cut => cut.DurationType == strDurationType && cut.MonthYear == _monthYear).ToList(); _from = DateTime.MaxValue; _to = DateTime.MinValue; foreach (Att_CutOffDuration cutOff in lstCutOffMonth) { if (_from > cutOff.DateStart) { _from = cutOff.DateStart; } if (_to < cutOff.DateEnd) { _to = cutOff.DateEnd; } } if (_from == DateTime.MaxValue || _to == DateTime.MinValue) { _from = _monthYear; _to = _monthYear; } } } else { if (EnumDropDown.SalaryTimeType.E_LASTMONTH.ToString() == gradeCfg.SalaryTimeType) { _from = new DateTime(monthYear.AddMonths(-1).Year, monthYear.AddMonths(-1).Month, day); } else //same month { _from = new DateTime(monthYear.Year, monthYear.Month, day); } _to = _from.AddMonths(1).AddMinutes(-1); } from = _from; to = _to; }
public static void GetSalaryDateRange(Cat_GradeAttendance gradeCfg, Sys_AllSetting objAppConfig, List<Att_CutOffDuration> lstCutOff, DateTime monthYear , out DateTime from, out DateTime to) { DateTime fromDate = new DateTime(monthYear.Year, monthYear.Month, 1); DateTime toDate = fromDate.AddMonths(1).AddMinutes(-1); if (gradeCfg != null) Att_AttendanceServices.GetSalaryDateRange(gradeCfg, lstCutOff, monthYear, out fromDate, out toDate); else { if (objAppConfig != null) Att_AttendanceServices.GetSalaryDateRange(objAppConfig, monthYear, out fromDate, out toDate); } from = fromDate; to = toDate; }
/// <summary> /// Kiem tra ngay lam viec, dua tren cau hinh Grade /// Tru cac ngay nghi le /// </summary> /// <param name="grade"></param> /// <param name="date"></param> /// <returns></returns> public static bool IsWorkDay(Cat_GradeAttendance grade, Hashtable rosterTable , List<Cat_DayOff> lstDayOff, DateTime date) { if (grade == null) return false; //throw new VNRException("Grade is not configured"); List<Cat_DayOff> lstDayWeekend = new List<Cat_DayOff>(); //if (lstDayOff != null) // lstDayWeekend = lstDayOff.Where(off => off.Type == HolidayType.E_WEEKEND_HLD.ToString() // || off.Type == HolidayType.E_HOLIDAY_HLD.ToString()).ToList(); if (lstDayOff != null) lstDayWeekend = lstDayOff.Where(off => off.Type == HolidayType.E_WEEKEND_HLD.ToString()).ToList(); if (grade.RosterType == GradeRosterType.E_ISROSTER.ToString() || grade.RosterType == GradeRosterType.E_ISROSTER_ORG.ToString()) { return Att_RosterServices.IsWorkDay(date, rosterTable); } else if (grade.RosterType == GradeRosterType.E_ISHOLIDAY.ToString()) { if (lstDayWeekend == null || lstDayWeekend.Count <= 0) return true; if (!lstDayWeekend.Exists(dof => dof.DateOff.Date == date.Date)) return true; } else if (grade.RosterType == GradeRosterType.E_ISDEFAULT.ToString())// dua tren roster Default { //Kiem tra xem co cau hinh nghi cuoi tuan trong ngay nghi if (lstDayWeekend != null && lstDayWeekend.Exists(dof => dof.DateOff.Date == date.Date)) return false; if ((date.DayOfWeek == DayOfWeek.Monday) && grade.WorkOnMondayID != null) { return true; } else if ((date.DayOfWeek == DayOfWeek.Tuesday) && grade.WorkOnTuesdayID != null) { return true; } else if ((date.DayOfWeek == DayOfWeek.Wednesday) && grade.WorkOnWednesdayID != null) { return true; } else if ((date.DayOfWeek == DayOfWeek.Thursday) && grade.WorkOnThursdayID != null) { return true; } else if ((date.DayOfWeek == DayOfWeek.Friday) && grade.WorkOnFridayID != null) { return true; } else if ((date.DayOfWeek == DayOfWeek.Saturday) && grade.WorkOnSaturdayID != null) { return true; } else if (date.DayOfWeek == DayOfWeek.Sunday && grade.WorkOnSundayID != null) { return true; } } return false; }
/// <summary> /// /// </summary> /// <param name="grade"></param> /// <param name="rosterTable"></param> /// <param name="date"></param> /// <returns></returns> public static Cat_Shift GetShift(Cat_GradeAttendance grade, Hashtable rosterTable, DateTime date) { //Doc Shift tu Roster Cat_Shift res = Att_RosterServices.GetShift(date, rosterTable); //Kiem tra co cau hinh Roster hay ko. neu co thi lay Shift theo Roster, ko thi lay theo Default //Neu ko co roster. if (res == null) { //Kiem tra cau hinh grade if (grade != null) { //Kiem tra cau hinh Shift trong grade neu thiet lap lich lam viec la 'Mac dinh-Default' if (grade.RosterType == GradeRosterType.E_ISDEFAULT.ToString())// dua tren roster Default { //Thu tu shift ~ ngay trong tuan tham khao file 'UserDataObject.cs if ((date.DayOfWeek == DayOfWeek.Monday) && grade.WorkOnMondayID != null) { res.ID = grade.WorkOnMondayID.Value; } else if ((date.DayOfWeek == DayOfWeek.Tuesday) && grade.WorkOnTuesdayID != null) { res.ID = grade.WorkOnTuesdayID.Value; } else if ((date.DayOfWeek == DayOfWeek.Wednesday) && grade.WorkOnWednesdayID != null) { res.ID = grade.WorkOnWednesdayID.Value; } else if ((date.DayOfWeek == DayOfWeek.Thursday) && grade.WorkOnThursdayID != null) { res.ID = grade.WorkOnThursdayID.Value; } else if ((date.DayOfWeek == DayOfWeek.Friday) && grade.WorkOnFridayID != null) { res.ID = grade.WorkOnFridayID.Value; } else if ((date.DayOfWeek == DayOfWeek.Saturday) && grade.WorkOnSaturdayID != null) { res.ID = grade.WorkOnSaturdayID.Value; } else if (date.DayOfWeek == DayOfWeek.Sunday && grade.WorkOnSundayID != null) { res.ID = grade.WorkOnSundayID.Value; } } } } return res; }
public static Double GetOTStandardWorkDays(int holidayCount, Cat_GradeAttendance gradeCfg, List<Cat_DayOff> listDayOff, List<Cat_Shift> listShift, Dictionary<DateTime, List<Guid?>> listMonthShifts, DateTime monthYear, DateTime dateFrom, DateTime dateTo) { Double result = 0; if (gradeCfg.IsFixedOT.HasValue && gradeCfg.IsFixedOT.Value) { result = gradeCfg.OTWorkDayFix.GetDouble(); } else if (gradeCfg.IsActualOT.HasValue && gradeCfg.IsActualOT.Value) { result = dateTo.Subtract(dateFrom).Days + 1; if (gradeCfg.IsActualOT.GetBoolean()) { result += gradeCfg.OTWorkdayActual.GetInteger(); } } else if (gradeCfg.IsRosterOT.HasValue && gradeCfg.IsRosterOT.Value) { if (gradeCfg.RosterType == GradeRosterType.E_ISROSTER.ToString()) { result = GetRosterStandardWorkDays(gradeCfg, listShift, listMonthShifts, dateFrom, dateTo); } else if (gradeCfg.RosterType == GradeRosterType.E_ISDEFAULT.ToString()) { result = GetGradeStandardWorkDays(gradeCfg, dateFrom, dateTo); } else if (gradeCfg.RosterType == GradeRosterType.E_ISHOLIDAY.ToString()) { int monthDayCount = dateTo.Subtract(dateFrom).Days + 1; result = monthDayCount - holidayCount; } } else if (gradeCfg.IsFormulaOT.HasValue && gradeCfg.IsFormulaOT.Value) { Formula formula = new Formula(gradeCfg.OTWorkdayFormula); if (gradeCfg.OTWorkdayFormula.Contains(Formula.FormulaConstant.DAYS_IN_MONTH_EXCLUDE_SUNDAY.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.DAYS_IN_MONTH_EXCLUDE_SUNDAY.ToString(), GetDaysInMonthExcludeSunday(gradeCfg, monthYear)); } if (gradeCfg.OTWorkdayFormula.Contains(Formula.FormulaConstant.DAYS_IN_MONTH_EXCLUDE_SUNDAY_HOLIDAY.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.DAYS_IN_MONTH_EXCLUDE_SUNDAY_HOLIDAY.ToString(), GetDaysInMonthExcludeSunday(gradeCfg, monthYear) - holidayCount); } if (gradeCfg.OTWorkdayFormula.Contains(Formula.FormulaConstant.WORKDAY_AVERAGE_PER_MONTH.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.WORKDAY_AVERAGE_PER_MONTH.ToString(), GetStandardWorkDays(monthYear.Year, listDayOff)); } if (gradeCfg.OTWorkdayFormula.Contains(Formula.FormulaConstant.D.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.D.ToString(), dateTo.Subtract(dateFrom).Days + 1); } if (gradeCfg.OTWorkdayFormula.Contains(Formula.FormulaConstant.H.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.H.ToString(), holidayCount); } if (gradeCfg.OTWorkdayFormula.Contains(Formula.FormulaConstant.S.ToString())) { int sundayCount = 0; for (DateTime date = dateFrom; date <= dateTo; date = date.AddDays(1)) { if (date.DayOfWeek == DayOfWeek.Sunday) { sundayCount++; } } formula.Parameters.Add(Formula.FormulaConstant.S.ToString(), sundayCount); } if (gradeCfg.OTWorkdayFormula.Contains(Formula.FormulaConstant.R.ToString())) { Double count = GetRosterStandardWorkDays(gradeCfg, listShift, listMonthShifts, dateFrom, dateTo); formula.Parameters.Add(Formula.FormulaConstant.R.ToString(), count); } if (gradeCfg.OTWorkdayFormula.Contains(Formula.FormulaConstant.R_NOT_H.ToString())) { Double count = GetRosterSdNotHoliDays(listMonthShifts, listDayOff, dateFrom, dateTo); formula.Parameters.Add(Formula.FormulaConstant.R_NOT_H.ToString(), count); } if (gradeCfg.OTWorkdayFormula.Contains(Formula.FormulaConstant.SAT.ToString())) { int satdayCount = 0; for (DateTime date = dateFrom; date <= dateTo; date = date.AddDays(1)) { if (date.DayOfWeek == DayOfWeek.Saturday) { satdayCount++; } } formula.Parameters.Add(Formula.FormulaConstant.SAT.ToString(), satdayCount); } result = Convert.ToDouble(formula.Evaluate()); } return result; }
private static double GetGradeStandardWorkDays(Cat_GradeAttendance gradeCfg, DateTime dateFrom, DateTime dateTo) { Double result = 0; for (DateTime date = dateFrom.Date; date <= dateTo.Date; date = date.AddDays(1)) { if (gradeCfg.RosterType == GradeRosterType.E_ISDEFAULT.ToString()) { if (Att_WorkDayHelper.IsWorkDay(date, gradeCfg, null)) { result++; } } } return result; }
private static int GetDaysInMonthExcludeSunday(Cat_GradeAttendance gradeCfg, DateTime monthYear) { int result = 0; DateTime dateFrom, dateTo; gradeCfg.GetSalaryDateRange(monthYear, out dateFrom, out dateTo); for (DateTime date = dateFrom; date <= dateTo; date = date.AddDays(1)) { if (date.DayOfWeek != DayOfWeek.Sunday) { result++; } } return result; }
/// <summary> /// Kiểm tra một ngày có phải là ngày làm việc không? /// Chỉ áp dụng cho trường hợp RosterType = E_ISDEFAULT /// </summary> /// <param name="date"></param> /// <param name="gradeCfg"></param> /// <param name="listDayOff"></param> /// <returns></returns> public static bool IsWorkDay(DateTime date, Cat_GradeAttendance gradeCfg, List<Cat_DayOff> listDayOff) { bool result = false; if (listDayOff == null || !listDayOff.Any(d => d.DateOff.Date == date.Date && d.Type == HolidayType.E_WEEKEND_HLD.ToString())) { if (gradeCfg.RosterType == GradeRosterType.E_ISDEFAULT.ToString()) { //if (date.DayOfWeek == DayOfWeek.Monday && gradeCfg.Cat_Shift != null) //{ // result = true; //} //else if (date.DayOfWeek == DayOfWeek.Tuesday && gradeCfg.Cat_Shift1 != null) //{ // result = true; //} //else if (date.DayOfWeek == DayOfWeek.Wednesday && gradeCfg.Cat_Shift2 != null) //{ // result = true; //} //else if (date.DayOfWeek == DayOfWeek.Thursday && gradeCfg.Cat_Shift3 != null) //{ // result = true; //} //else if (date.DayOfWeek == DayOfWeek.Friday && gradeCfg.Cat_Shift4 != null) //{ // result = true; //} //else if (date.DayOfWeek == DayOfWeek.Saturday && gradeCfg.Cat_Shift5 != null) //{ // result = true; //} //else if (date.DayOfWeek == DayOfWeek.Sunday && gradeCfg.Cat_Shift6 != null) //{ result = true; //} } } return result; }
/// <summary> /// Xac dinh thang tinh luong cua thoi gian /// </summary> /// <param name="grade"></param> /// <param name="monthYear"></param> /// <param name="from"></param> /// <param name="to"></param> public static void GetMonthSalary(Cat_GradeAttendance gradeCfg, DateTime dateTime , out DateTime monthYear) { int day = Convert.ToInt32(gradeCfg.SalaryTimeDay); //tan.do: check when day is 0 day = day == 0 ? 1 : day; DateTime from = dateTime; if (EnumDropDown.SalaryTimeType.E_LASTMONTH.ToString() == gradeCfg.SalaryTimeType) { from = new DateTime(dateTime.AddMonths(-1).Year, dateTime.AddMonths(-1).Month, day); } else //same month { from = new DateTime(dateTime.Year, dateTime.Month, day); } DateTime to = from.AddMonths(1).AddMinutes(-1); if (from <= dateTime && to >= dateTime) { monthYear = new DateTime(dateTime.Year, dateTime.Month, 1); } else { monthYear = new DateTime(dateTime.AddMonths(1).Year, dateTime.AddMonths(1).Month, 1); } }
public void AnalyseTotalLeaveDaysAndHours(Att_LeaveDay LeaveDay, Cat_LeaveDayType LeaveDayType, Hre_Profile profile, Cat_GradeAttendance gradeCfg, List<Att_Roster> lstRoster, List<Att_RosterGroup> lstRosterGroup, List<Hre_WorkHistory> listWorkHistory, List<Cat_DayOff> lstHoliday, List<Cat_Shift> lstShift) { if (LeaveDay.DurationType == null) return; #region data string LeaveDayTypeCode = string.Empty; if (LeaveDayType != null) LeaveDayTypeCode = LeaveDayType.Code; if (gradeCfg == null) return; DateTime dateFrom = LeaveDay.DateStart.Date; DateTime dateTo = LeaveDay.DateEnd; dateTo = dateTo.AddDays(1).AddMinutes(-1); string E_ROSTERGROUP = RosterType.E_ROSTERGROUP.ToString(); List<Att_Roster> lstRosterByProfile = lstRoster.Where(m => m.ProfileID == profile.ID && m.DateStart <= dateTo && m.DateEnd >= dateFrom).ToList(); List<Att_Roster> lstRosterByProfileTypeGroup = lstRosterByProfile.Where(m => m.Type == E_ROSTERGROUP).ToList(); List<Hre_WorkHistory> listWorkHistoryByProfile = listWorkHistory.Where(m => m.ProfileID == profile.ID && m.DateEffective < dateTo).ToList(); var listRosterEntity = lstRosterByProfile.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(); Dictionary<DateTime, Cat_Shift> listMonthShifts = Att_AttendanceLib.GetDailyShifts(profile.ID, dateFrom, dateTo, listRosterEntity, listRosterGroupEntity, lstShift); double leaveDays = 0; double leaveHours = 0; #endregion if (LeaveDay.DurationType != LeaveDayDurationType.E_FULLSHIFT.ToString()) { DateTime dateLeave = LeaveDay.DateStart.Date; //Check co ca ko if (gradeCfg != null && Att_WorkDayHelper.IsWorkDay(dateLeave, gradeCfg, listMonthShifts, lstHoliday)) { if (listMonthShifts.ContainsKey(dateLeave) && listMonthShifts[dateLeave] != null && listMonthShifts[dateLeave].WorkHours != null && listMonthShifts[dateLeave].WorkHours != 0) { Cat_Shift Shift = listMonthShifts[dateLeave]; //Có ca thi lây giờ nghỉ giua ca để mà tính thời gian thực nghỉ //Nếu như trừ thời gian nghỉ ra khỏi giờ nghi trưa mà lơn hơn workhour của ca thì lấy max la workhour của ca DateTime ShiftBreakIn = dateLeave.Add(Shift.InTime.TimeOfDay).AddHours(Shift.CoBreakIn); DateTime ShiftBreakOut = dateLeave.Add(Shift.InTime.TimeOfDay).AddHours(Shift.CoBreakOut); if (LeaveDay.DateStart < ShiftBreakOut && LeaveDay.DateEnd > ShiftBreakIn) { //neu co long nhau if (ShiftBreakIn > LeaveDay.DateStart) leaveHours = (ShiftBreakIn - LeaveDay.DateStart).TotalHours; if (LeaveDay.DateEnd > ShiftBreakOut) leaveHours += (LeaveDay.DateEnd - ShiftBreakOut).TotalHours; leaveDays = leaveHours / Shift.WorkHours ?? 8; } else { leaveHours = (LeaveDay.DateEnd - LeaveDay.DateStart).TotalHours; leaveDays = leaveHours / Shift.WorkHours ?? 8; //neu ko long nhau } } else //Ko có ca làm việc { //Nếu ko có ca thì lấy giờ out trừ giờ in leaveHours = (LeaveDay.DateEnd - LeaveDay.DateStart).TotalHours; leaveDays = leaveHours / 8; } } } else //Loại FullShift { if (LeaveDay.DurationType == null) { LeaveDay.DurationType = LeaveDayDurationType.E_FULLSHIFT.ToString(); } if (profile == null) return; bool isSetFullLeaveDay = false; if (!string.IsNullOrEmpty(LeaveDayTypeCode) && (LeaveDayTypeCode == "SICK" || LeaveDayTypeCode == "PRG" || LeaveDayTypeCode == "SU" || LeaveDayTypeCode == "SD" || LeaveDayTypeCode == "D" || LeaveDayTypeCode == "DP" || LeaveDayTypeCode == "PSN" || LeaveDayTypeCode == "M" || LeaveDayTypeCode == "DSP")) { for (DateTime idx = dateFrom; idx <= dateTo; idx = idx.AddDays(1)) { if (!lstHoliday.Any(m => m.DateOff == idx)) { leaveDays += 1; Cat_Shift ShiftByDay = null; if (listMonthShifts.ContainsKey(idx)) { ShiftByDay = listMonthShifts[idx]; } if (ShiftByDay != null) { leaveHours += ShiftByDay.WorkHours ?? 8; } else { leaveHours += 8; } } isSetFullLeaveDay = true; } } if (isSetFullLeaveDay == false) { for (DateTime idx = dateFrom; idx <= dateTo; idx = idx.AddDays(1)) { if (gradeCfg != null && Att_WorkDayHelper.IsWorkDay(idx, gradeCfg, listMonthShifts, lstHoliday)) { leaveDays += 1; Cat_Shift ShiftByDay = null; if (listMonthShifts.ContainsKey(idx)) { ShiftByDay = listMonthShifts[idx]; } if (ShiftByDay != null) { leaveHours += ShiftByDay.WorkHours ?? 8; } } } } } if (LeaveDay.LeaveDays == null || LeaveDay.LeaveDays != leaveDays) { LeaveDay.LeaveDays = leaveDays; } if (LeaveDay.LeaveHours == null || LeaveDay.LeaveHours != leaveHours) { LeaveDay.LeaveHours = leaveHours; } }
private int ComputeAttendance(IUnitOfWork unitOfWork, Guid userID, DateTime monthYear, Guid cutOffDurationID, DateTime attendanceFrom, DateTime attendanceTo, Hre_ProfileEntity profile, Cat_GradeAttendance gradeCfg, List<Cat_Shift> listShift, List<Att_AnnualDetail> listAnnualDetailByProfile, List<Hre_HDTJob> listHDTJobByProfile, List<Att_LeaveDayEntity> listLeaveDayByProfile, List<Cat_LeaveDayType> listLeaveDayType, List<Att_OvertimeEntity> listOvertimeByProfile, List<Cat_OvertimeType> listOvertimeType, List<Att_PregnancyEntity> listPregnancyByProfile, List<Cat_LateEarlyRule> listLateEarlyRule, List<Att_Workday> listWorkDayByProfile, List<Att_AttendanceTableEntity> listPreAttendanceTableByProfile, List<Att_TimeOffInLieuEntity> listTimeOffInLieuByProfile, Sys_AllSetting notAutoRegHolidayLeave, Sys_AllSetting otholidayscompute400, Sys_AllSetting missTAM_LeaveType, Dictionary<DateTime, List<Guid?>> listMonthShiftID, List<Cat_DayOff> listHoliday) { Guid profileID = profile.ID; if (gradeCfg == null || profile == null) { return 0; } DateTime midCutOffDate = attendanceTo; bool isMidCutOffDay = false; #region Tạo Att_AttendanceTable theo khoảng thời gian Att_AttendanceTable attendanceTable = new Att_AttendanceTable(); unitOfWork.AddObject(typeof(Att_AttendanceTable), attendanceTable); attendanceTable.Status = AttendanceTableStatus.E_WAITING.ToString(); attendanceTable.ID = Guid.NewGuid(); attendanceTable.ProfileID = profileID; attendanceTable.MonthYear = monthYear; attendanceTable.DateStart = attendanceFrom; attendanceTable.DateEnd = attendanceTo; double anlDayTaken = 0D; double sickDayTaken = 0D; double coBeginPeriod = 0D; double coEndPeriod = 0D; if (cutOffDurationID != Guid.Empty) { attendanceTable.CutOffDurationID = cutOffDurationID; } //Tính công đến ngày cấu hình trong grade, những ngày sau mặc định full công - Khách hàng CPG if (gradeCfg != null && gradeCfg.IsMonthlyMidCutOff == true && gradeCfg.MidCutOffDay > 0) { if (!profile.DateQuit.HasValue || profile.DateQuit > attendanceTo) { midCutOffDate = new DateTime(monthYear.Year, monthYear.Month, gradeCfg.MidCutOffDay.Value); //Luôn tạo một dòng Ứng công lúc tính công, kô cần biết có nghỉ không Att_AdvanceTableItem advanceTableItem = new Att_AdvanceTableItem(); advanceTableItem.Att_AttendanceTable = attendanceTable; advanceTableItem.DateFrom = midCutOffDate.AddDays(1); advanceTableItem.DateTo = attendanceTo; isMidCutOffDay = true; } } #endregion #region Tạo Att_AttendanceTableItem theo khoảng thời gian List<Att_AttendanceTableItem> listAttendanceTableItemByProfile = new List<Att_AttendanceTableItem>(); for (DateTime date = attendanceFrom.Date; date <= attendanceTo; date = date.AddDays(1)) { var workdayByProfile = listWorkDayByProfile.Where(d => d.WorkDate.Date == date).FirstOrDefault(); Guid? shiftID1 = Guid.Empty; Guid? shiftID2 = Guid.Empty; var shiftByDate = listMonthShiftID.Where(d => d.Key.Date == date).Select(d => d.Value).FirstOrDefault(); if (shiftByDate != null) { if (shiftByDate.Count() > 0) { shiftID1 = shiftByDate[0]; } if (shiftByDate.Count() > 1) { shiftID2 = shiftByDate[1]; } } if (workdayByProfile == null && gradeCfg.EDType == PayrollComputeMethod.E_SUBTRACT.ToString()) { if (shiftID1.HasValue && shiftID1 != Guid.Empty) { workdayByProfile = new Att_Workday { ShiftID = shiftID1, ShiftApprove = shiftID1, ShiftActual = shiftID1, WorkDate = date }; if (shiftID2.HasValue && shiftID2 != Guid.Empty) { workdayByProfile.Shift2ID = shiftID2; workdayByProfile.ShiftApprove2 = shiftID2; workdayByProfile.ShiftActual2 = shiftID2; } if (listHoliday.Any(d => d.DateOff.Date == date)) { workdayByProfile.Type = WorkdayType.E_HOLIDAY.ToString(); } } } Att_AttendanceTableItem attendanceTableItem = new Att_AttendanceTableItem(); listAttendanceTableItemByProfile.Add(attendanceTableItem); attendanceTableItem.ID = Guid.NewGuid(); attendanceTableItem.Att_AttendanceTable = attendanceTable; attendanceTableItem.DutyCode = DutyCode.E_OFF.ToString(); attendanceTableItem.WorkDate = date; double nightDuration = 0F; double workDuration = 0F; attendanceTableItem.WorkPaidHours = 0; attendanceTableItem.PaidLeaveHours = 0; attendanceTableItem.UnpaidLeaveHours = 0; attendanceTableItem.LateEarlyMinutes = 0; attendanceTableItem.LateInMinutes = 0; attendanceTableItem.EarlyOutMinutes = 0; attendanceTableItem.LeaveHours = 0; attendanceTableItem.LeaveDays = 0; attendanceTableItem.WorkHourFirstHaftShift = 0; attendanceTableItem.WorkHourLastHaftShift = 0; if (workdayByProfile != null) { attendanceTableItem.MissInOutReasonID = workdayByProfile.MissInOutReason; attendanceTableItem.FirstInTime = workdayByProfile.FirstInTime; attendanceTableItem.LastOutTime = workdayByProfile.LastOutTime; attendanceTableItem.RootInTime = workdayByProfile.FirstInTime; attendanceTableItem.RootOutTime = workdayByProfile.LastOutTime; attendanceTableItem.ShiftID = workdayByProfile.ShiftID; attendanceTableItem.Shift2ID = workdayByProfile.Shift2ID; List<DateTime?> listInTime = new List<DateTime?>(); List<DateTime?> listOutTime = new List<DateTime?>(); listInTime.Add(workdayByProfile.InTime1); listInTime.Add(workdayByProfile.InTime2); listInTime.Add(workdayByProfile.InTime3); listInTime.Add(workdayByProfile.InTime4); listOutTime.Add(workdayByProfile.OutTime1); listOutTime.Add(workdayByProfile.OutTime2); listOutTime.Add(workdayByProfile.OutTime3); listOutTime.Add(workdayByProfile.OutTime4); attendanceTableItem.FirstInTime = listInTime.Where(d => d.HasValue).OrderBy(d => d).FirstOrDefault(); attendanceTableItem.LastOutTime = listOutTime.Where(d => d.HasValue).OrderBy(d => d).LastOrDefault(); if (workdayByProfile.ShiftApprove.HasValue) { attendanceTableItem.ShiftID = workdayByProfile.ShiftApprove.Value; } if (workdayByProfile.ShiftApprove2.HasValue) { attendanceTableItem.Shift2ID = workdayByProfile.ShiftApprove2.Value; } if (gradeCfg.AttendanceMethod == AttendanceMethod.E_FULL.ToString()) { if (listMonthShiftID.Any(d => d.Key.Date == date)) { //Bao.Tran: khi không kiểm tra vào ra thì ưu tiên ca đã tạo trong lịch làm việc if (shiftID1 != Guid.Empty) { attendanceTableItem.ShiftID = shiftID1; } if (shiftID2 != Guid.Empty) { attendanceTableItem.Shift2ID = shiftID2; } } //Bao.Tran: yêu cầu nếu công ko kiểm tra in/out thì không lấy in/out attendanceTableItem.FirstInTime = null; attendanceTableItem.LastOutTime = null; //comment code này do ảnh hưởng task 0046036 : ko tính được ngày nghỉ lễ ////Bao.Tran: do khi THNC cũ, Nếu ko bỏ type thì nó sẽ tính ngày công trên là holiday (attendanceTableItem.IsHoliday = true;) //workdayByProfile.Type = WorkdayType.E_NORMAL.ToString(); } //kiểm tra ngày làm việc có Lịch làm việc hay ko? if (attendanceTableItem.ShiftID != null && workdayByProfile.FirstInTime != null && workdayByProfile.LastOutTime != null) { #region Kiểm tra HDTJob var listHDTJobByProfileByDate = listHDTJobByProfile.Where(d => (d.DateFrom.Value.Date <= date && d.DateTo == null) || (d.DateTo != null && d.DateFrom.Value.Date <= date && d.DateTo.Value.Date >= date)).ToList(); foreach (var HDTJobByProfile in listHDTJobByProfileByDate) { if (HDTJobByProfile != null) { attendanceTableItem.HDTJobType = HDTJobByProfile.Type; } } #endregion } } var shiftByProfile1 = listShift.Where(d => d.ID == attendanceTableItem.ShiftID).FirstOrDefault(); var shiftByProfile2 = listShift.Where(d => d.ID == attendanceTableItem.Shift2ID).FirstOrDefault(); if (shiftByProfile1 != null) { attendanceTableItem.Cat_Shift = shiftByProfile1; attendanceTableItem.AvailableHours = shiftByProfile1.udAvailableHours; } if (shiftByProfile2 != null) { attendanceTableItem.Cat_Shift1 = shiftByProfile2; } if ((workdayByProfile != null && workdayByProfile.Type == WorkdayType.E_HOLIDAY.ToString()) || (attendanceTableItem.ShiftID.HasValue && attendanceTableItem.ShiftID != Guid.Empty)) { //Ngày đang xét là ngày làm việc bình thường attendanceTableItem.DutyCode = DutyCode.E_ON.ToString(); if (workdayByProfile.Type == WorkdayType.E_HOLIDAY.ToString()) { attendanceTableItem.IsHoliday = true; } } else { //Ngày đang xét không phải là ngày làm việc bình thường attendanceTableItem.DutyCode = DutyCode.E_OFF.ToString(); } #region Kiểm tra ngày nghỉ - leaveday if (attendanceTableItem.DutyCode != DutyCode.E_OFF.ToString()) { var listLeaveDayByProfileByDate = listLeaveDayByProfile.Where(d => d.DateStart.Date <= date && d.DateEnd.Date >= date).ToList(); foreach (var leaveDayByProfile in listLeaveDayByProfileByDate) { if (leaveDayByProfile != null) { double leaveHours = 0D; double leaveDays = 0D; var leaveDayType = listLeaveDayType.Where(d => d.ID == leaveDayByProfile.LeaveDayTypeID).FirstOrDefault(); var standardWorkHours = attendanceTableItem.AvailableHours; if (leaveDayByProfile.DurationType == LeaveDayDurationType.E_FULLSHIFT.ToString()) { //Lấy giờ nghỉ của ngày đang xét dựa vào ca làm việc leaveHours = standardWorkHours; leaveDays = 1;//Nghỉ full shift } else { leaveHours = leaveDayByProfile.LeaveHours.GetDouble(); leaveDays = leaveDayByProfile.LeaveDays.GetDouble(); } leaveHours = leaveHours > standardWorkHours ? standardWorkHours : leaveHours; leaveDays = leaveDays > 1 ? 1 : leaveDays;//Tối đa là nghỉ 1 ngày if (!attendanceTableItem.LeaveTypeID.HasValue) { attendanceTableItem.LeaveTypeID = leaveDayByProfile.LeaveDayTypeID; attendanceTableItem.Cat_LeaveDayType = leaveDayType; attendanceTableItem.LeaveHours = leaveHours; attendanceTableItem.LeaveDays = leaveDays; } else if (!attendanceTableItem.ExtraLeaveTypeID.HasValue) { attendanceTableItem.ExtraLeaveTypeID = leaveDayByProfile.LeaveDayTypeID; attendanceTableItem.Cat_LeaveDayType1 = leaveDayType; attendanceTableItem.ExtraLeaveHours = leaveHours; attendanceTableItem.ExtraLeaveDays = leaveDays; } if (leaveDayType != null && leaveDays > 0) { if (leaveDayType.Code == LeavedayTypeCode.ANL.ToString()) { anlDayTaken += leaveDays; } if (leaveDayType.Code == LeavedayTypeCode.SICK.ToString()) { sickDayTaken += leaveDays; } } } } } #endregion #region Kiểm tra làm thêm - overtime if (gradeCfg != null && gradeCfg.IsReceiveOvertimeBonus.Get_Boolean()) { var listOvertimeByProfileByDate = listOvertimeByProfile.Where(d => d.WorkDate.Date == date).ToList(); foreach (var overtime in listOvertimeByProfileByDate) { if (overtime != null) { double overtimeHours = overtime.ConfirmHours; string overTimeStatus = OverTimeStatus.E_APPROVED.ToString(); if (overTimeStatus == OverTimeStatus.E_APPROVED.ToString()) { overtimeHours = overtime.ApproveHours.GetDouble(); } else if (overTimeStatus == OverTimeStatus.E_CONFIRM.ToString()) { overtimeHours = overtime.ConfirmHours; } if (!attendanceTableItem.OvertimeTypeID.HasValue) { attendanceTableItem.OvertimeTypeID = overtime.OvertimeTypeID; attendanceTableItem.Cat_OvertimeType = listOvertimeType.Where(s => s.ID == overtime.OvertimeTypeID).FirstOrDefault(); attendanceTableItem.OvertimeDurationType = overtime.DurationType; attendanceTableItem.OvertimeRegisterHours = overtime.RegisterHours; attendanceTableItem.OvertimeHours = overtimeHours; } else if (!attendanceTableItem.ExtraOvertimeTypeID.HasValue) { attendanceTableItem.ExtraOvertimeTypeID = overtime.OvertimeTypeID; attendanceTableItem.Cat_OvertimeType1 = listOvertimeType.Where(s => s.ID == overtime.OvertimeTypeID).FirstOrDefault(); attendanceTableItem.ExtraOvertimeDurationType = overtime.DurationType; attendanceTableItem.ExtraOvertimeRegisterHours = overtime.RegisterHours; attendanceTableItem.ExtraOvertimeHours = overtimeHours; } else if (!attendanceTableItem.ExtraOvertimeType2ID.HasValue) { attendanceTableItem.ExtraOvertimeType2ID = overtime.OvertimeTypeID; attendanceTableItem.Cat_OvertimeType2 = listOvertimeType.Where(s => s.ID == overtime.OvertimeTypeID).FirstOrDefault(); attendanceTableItem.ExtraOvertimeDurationType2 = overtime.DurationType; attendanceTableItem.ExtraOvertimeRegisterHours2 = overtime.RegisterHours; attendanceTableItem.ExtraOvertimeHours2 = overtimeHours; } else if (!attendanceTableItem.ExtraOvertimeType3ID.HasValue) { attendanceTableItem.ExtraOvertimeType3ID = overtime.OvertimeTypeID; attendanceTableItem.Cat_OvertimeType3 = listOvertimeType.Where(s => s.ID == overtime.OvertimeTypeID).FirstOrDefault(); attendanceTableItem.ExtraOvertimeDurationType3 = overtime.DurationType; attendanceTableItem.ExtraOvertimeRegisterHours3 = overtime.RegisterHours; attendanceTableItem.ExtraOvertimeHours3 = overtimeHours; } } } } #endregion #region Kiểm tra có thai sản không var pregnancyByProfile = listPregnancyByProfile.Where(d => date >= d.DateStart && date <= d.DateEnd).FirstOrDefault(); if (pregnancyByProfile != null) { attendanceTableItem.IsHavingPregTreatment = true; } #endregion #region Nhân viên đã nghỉ hoặc chưa đi làm if ((profile.DateQuit.HasValue && profile.DateQuit.Value.Date <= date.Date) || (profile.DateHire.HasValue && profile.DateHire.Value.Date > date.Date)) { if (attendanceTableItem.DutyCode == DutyCode.E_ON.ToString()) { if (profile.DateHire.HasValue && profile.DateHire.Value.Date > date.Date) { if (shiftByProfile1 != null) { attendanceTableItem.udNotHiredHours = shiftByProfile1.WorkHours.GetDouble(); } else { attendanceTableItem.udNotHiredHours = attendanceTableItem.udStandardWorkHours; } if (shiftByProfile2 != null) { attendanceTableItem.udNotHiredHours += shiftByProfile2.WorkHours.GetDouble(); } } if (profile.DateQuit.HasValue && profile.DateQuit.Value.Date <= date.Date) { if (shiftByProfile1 != null) { attendanceTableItem.udTerminatedHours = shiftByProfile1.WorkHours.GetDouble(); } else { attendanceTableItem.udTerminatedHours = attendanceTableItem.udStandardWorkHours; } if (shiftByProfile2 != null) { attendanceTableItem.udTerminatedHours += shiftByProfile2.WorkHours.GetDouble(); } } } attendanceTableItem.Cat_LeaveDayType = null; continue; } #endregion #region Loại ngày nghỉ là ngày làm việc if (attendanceTableItem.Cat_LeaveDayType != null) { //Trường hợp ngày nghỉ tính như ngày đi làm => không tính nghỉ if (attendanceTableItem.Cat_LeaveDayType.IsWorkDay) { attendanceTableItem.WorkHours += attendanceTableItem.LeaveHours; attendanceTableItem.WorkPaidHours += attendanceTableItem.LeaveHours; attendanceTableItem.LeaveWorkDayHour = attendanceTableItem.LeaveHours; attendanceTableItem.LeaveWorkDayDays = attendanceTableItem.LeaveHours / attendanceTableItem.udStandardWorkHours; attendanceTableItem.Cat_LeaveDayType2 = attendanceTableItem.Cat_LeaveDayType; attendanceTableItem.Cat_LeaveDayType = null; attendanceTableItem.LeaveHours = 0; attendanceTableItem.LeaveDays = 0; } else { attendanceTableItem.PaidLeaveHours += attendanceTableItem.LeaveHours * attendanceTableItem.Cat_LeaveDayType.PaidRate; attendanceTableItem.UnpaidLeaveHours += attendanceTableItem.LeaveHours * (1 - attendanceTableItem.Cat_LeaveDayType.PaidRate); attendanceTableItem.PaidLeaveDays = attendanceTableItem.PaidLeaveHours / attendanceTableItem.udStandardWorkHours; attendanceTableItem.UnpaidLeaveDays = attendanceTableItem.UnpaidLeaveHours / attendanceTableItem.udStandardWorkHours; } } if (attendanceTableItem.Cat_LeaveDayType1 != null) { if (attendanceTableItem.Cat_LeaveDayType1.IsWorkDay) { attendanceTableItem.WorkHours += attendanceTableItem.ExtraLeaveHours; attendanceTableItem.WorkPaidHours += attendanceTableItem.ExtraLeaveHours; attendanceTableItem.Cat_LeaveDayType1 = null; attendanceTableItem.ExtraLeaveHours = 0; } else { attendanceTableItem.PaidLeaveHours += attendanceTableItem.ExtraLeaveHours * attendanceTableItem.Cat_LeaveDayType1.PaidRate; attendanceTableItem.UnpaidLeaveHours += attendanceTableItem.ExtraLeaveHours * (1 - attendanceTableItem.Cat_LeaveDayType1.PaidRate); } } #endregion if (attendanceTableItem.DutyCode == DutyCode.E_ON.ToString()) { #region IsHavingPregTreatment if (attendanceTableItem.IsHavingPregTreatment) { if ((attendanceTableItem.WorkPaidHours + attendanceTableItem.PaidLeaveHours) > attendanceTableItem.AvailableHours) { attendanceTableItem.WorkPaidHours = attendanceTableItem.AvailableHours - attendanceTableItem.PaidLeaveHours; } else { attendanceTableItem.WorkPaidHours = attendanceTableItem.WorkPaidHours; } } #endregion #region LateEarlyMinutes attendanceTableItem.LateEarlyMinutes = (int)workdayByProfile.LateEarlyDuration.GetDouble(); attendanceTableItem.RealLateEarlyMinutes = attendanceTableItem.LateEarlyMinutes; #endregion #region Tính số giờ đi làm if (workdayByProfile != null && shiftByProfile1 != null) { DateTime timeShiftStart1 = workdayByProfile.WorkDate.Date.Add(shiftByProfile1.InTime.TimeOfDay); DateTime timeShiftEnd1 = timeShiftStart1.AddHours(shiftByProfile1.CoOut); //Thời gian bắt đầu và kết thúc nghỉ giữa ca - dùng cho tính toán DateTime timeShiftBreakIn1 = timeShiftStart1.AddHours(shiftByProfile1.CoBreakIn); DateTime timeShiftBreakOut1 = timeShiftStart1.AddHours(shiftByProfile1.CoBreakOut); workDuration = GetDuration(workdayByProfile, timeShiftStart1, timeShiftEnd1, timeShiftBreakIn1, timeShiftBreakOut1, shiftByProfile1.InOutDynamic); #region Tính số giờ làm ca đêm if (shiftByProfile1.IsNightShift) { DateTime nightTimeStart = workdayByProfile.WorkDate.Date.AddHours(22); DateTime nightTimeEnd = workdayByProfile.WorkDate.Date.AddDays(1).AddHours(6); nightTimeStart = workdayByProfile.WorkDate.Date.Add(shiftByProfile1.NightTimeStart.Value.TimeOfDay); nightTimeEnd = workdayByProfile.WorkDate.Date.Add(shiftByProfile1.NightTimeEnd.Value.TimeOfDay); nightTimeEnd = nightTimeStart > nightTimeEnd ? nightTimeEnd.AddDays(1) : nightTimeEnd; //Truong hop nghi giua ca nam trong khoang bat dau ca dem nightDuration = GetDuration(workdayByProfile, nightTimeStart, nightTimeEnd, timeShiftBreakIn1, timeShiftBreakOut1, shiftByProfile1.InOutDynamic); } #endregion } if (workdayByProfile != null && shiftByProfile2 != null) { DateTime timeShiftStart2 = workdayByProfile.WorkDate.Date.Add(shiftByProfile2.InTime.TimeOfDay); DateTime timeShiftEnd2 = timeShiftStart2.AddHours(shiftByProfile2.CoOut); //Thời gian bắt đầu và kết thúc nghỉ giữa ca - dùng cho tính toán DateTime timeShiftBreakIn2 = timeShiftStart2.AddHours(shiftByProfile2.CoBreakIn); DateTime timeShiftBreakOut2 = timeShiftStart2.AddHours(shiftByProfile2.CoBreakOut); workDuration += GetDuration(workdayByProfile, timeShiftStart2, timeShiftEnd2, timeShiftBreakIn2, timeShiftBreakOut2, shiftByProfile2.InOutDynamic); #region Tính số giờ làm ca đêm if (shiftByProfile2.IsNightShift) { DateTime nightTimeStart = workdayByProfile.WorkDate.Date.AddHours(22); DateTime nightTimeEnd = workdayByProfile.WorkDate.Date.AddDays(1).AddHours(6); nightTimeStart = workdayByProfile.WorkDate.Date.Add(shiftByProfile2.NightTimeStart.Value.TimeOfDay); nightTimeEnd = workdayByProfile.WorkDate.Date.Add(shiftByProfile2.NightTimeEnd.Value.TimeOfDay); nightTimeEnd = nightTimeStart > nightTimeEnd ? nightTimeEnd.AddDays(1) : nightTimeEnd; //Truong hop nghi giua ca nam trong khoang bat dau ca dem nightDuration = GetDuration(workdayByProfile, nightTimeStart, nightTimeEnd, timeShiftBreakIn2, timeShiftBreakOut2, shiftByProfile2.InOutDynamic); } #endregion } attendanceTableItem.NightShiftHours = (nightDuration / 60);//lưu số giờ attendanceTableItem.WorkPaidHours = (workDuration / 60);//lưu số giờ attendanceTableItem.WorkHours = (workDuration / 60);//lưu số giờ attendanceTableItem.WorkPaidHours = attendanceTableItem.WorkPaidHours < 0 ? 0 : attendanceTableItem.WorkPaidHours; attendanceTableItem.WorkPaidHours = attendanceTableItem.WorkPaidHours > attendanceTableItem.AvailableHours ? attendanceTableItem.AvailableHours : attendanceTableItem.WorkPaidHours; #endregion if (gradeCfg.AttendanceMethod == AttendanceMethod.E_FULL.ToString()) { #region gradeCfg.AttendanceMethod = E_FULL if (shiftByProfile1 != null && shiftByProfile1.IsNightShift == true) { if (shiftByProfile1.NightTimeEnd != null && shiftByProfile1.NightTimeStart != null) { DateTime dateStartNightShift = shiftByProfile1.NightTimeStart.Value; DateTime dateEndNightShift = shiftByProfile1.NightTimeEnd.Value; if (dateStartNightShift > dateEndNightShift) { dateEndNightShift = dateEndNightShift.AddDays(1); } attendanceTableItem.NightShiftHours = dateEndNightShift.Subtract(dateStartNightShift).TotalHours; } else { attendanceTableItem.NightShiftHours = shiftByProfile1.WorkHours ?? 0; } } else if (shiftByProfile2 != null && shiftByProfile2.IsNightShift == true) { if (shiftByProfile2.NightTimeEnd != null && shiftByProfile2.NightTimeStart != null) { DateTime dateStartNightShift = shiftByProfile2.NightTimeStart.Value; DateTime dateEndNightShift = shiftByProfile2.NightTimeEnd.Value; if (dateStartNightShift > dateEndNightShift) { dateEndNightShift = dateEndNightShift.AddDays(1); } attendanceTableItem.NightShiftHours = dateEndNightShift.Subtract(dateStartNightShift).TotalHours; } else { attendanceTableItem.NightShiftHours = shiftByProfile2.WorkHours ?? 0; } } if ((shiftByProfile1 != null && shiftByProfile1.IsNightShift == true) || shiftByProfile2 != null && shiftByProfile2.IsNightShift == true) { if (attendanceTableItem.Cat_LeaveDayType != null) { double hourLeave = attendanceTableItem.LeaveHours + attendanceTableItem.PaidLeaveHours + attendanceTableItem.ExtraLeaveHours; attendanceTableItem.NightShiftHours = attendanceTableItem.NightShiftHours - hourLeave; if (attendanceTableItem.NightShiftHours < 0) { attendanceTableItem.NightShiftHours = 0; } } } if (attendanceTableItem.IsHoliday) { attendanceTableItem.LeaveHours = attendanceTableItem.PaidLeaveHours = 0; attendanceTableItem.WorkPaidHours = attendanceTableItem.LateEarlyMinutes = 0; attendanceTableItem.UnpaidLeaveHours = attendanceTableItem.AvailableHours; bool isNoLongerWorking = false; if ((profile.DateHire.HasValue && attendanceTableItem.WorkDate < profile.DateHire.Value) || (profile.DateQuit.HasValue && attendanceTableItem.WorkDate >= profile.DateQuit.Value)) { isNoLongerWorking = true; } if (!attendanceTableItem.IsHavingPregTreatment && !isNoLongerWorking && (notAutoRegHolidayLeave == null || notAutoRegHolidayLeave.Value1 != bool.TrueString)) { attendanceTableItem.WorkPaidHours = 0; attendanceTableItem.LateEarlyMinutes = 0; attendanceTableItem.UnpaidLeaveHours = 0; attendanceTableItem.LeaveHours = attendanceTableItem.AvailableHours; attendanceTableItem.PaidLeaveHours = attendanceTableItem.AvailableHours; attendanceTableItem.Cat_LeaveDayType = listLeaveDayType.Where(d => d.Code == LeavedayTypeCode.HLD.ToString()).FirstOrDefault(); } } attendanceTableItem.WorkHours = 0;//Thời gian làm việc = 0 attendanceTableItem.WorkPaidHours = attendanceTableItem.AvailableHours - attendanceTableItem.UnpaidLeaveHours - attendanceTableItem.PaidLeaveHours; #endregion } #region Trường hợp tăng ca trong ngày lễ if (attendanceTableItem.Cat_LeaveDayType != null && attendanceTableItem.Cat_LeaveDayType.Code == LeavedayTypeCode.HLD.ToString() && (otholidayscompute400 == null || otholidayscompute400.Value1 != bool.TrueString) && attendanceTableItem.Cat_OvertimeType != null) { var totalOvertimeHours = attendanceTableItem.OvertimeHours + attendanceTableItem.ExtraOvertimeHours + attendanceTableItem.ExtraOvertimeHours2 + attendanceTableItem.ExtraOvertimeHours3; if (gradeCfg.EDType == PayrollComputeMethod.E_SUBTRACT.ToString()) { if (attendanceTableItem.AvailableHours > totalOvertimeHours) { attendanceTableItem.LeaveHours = attendanceTableItem.AvailableHours - totalOvertimeHours; attendanceTableItem.ExtraLeaveHours = totalOvertimeHours; attendanceTableItem.PaidLeaveHours = attendanceTableItem.LeaveHours; attendanceTableItem.Cat_LeaveDayType1 = null; } else { attendanceTableItem.Cat_LeaveDayType = null; attendanceTableItem.LeaveHours = attendanceTableItem.AvailableHours; attendanceTableItem.PaidLeaveHours = 0; } } else { if (attendanceTableItem.AvailableHours >= totalOvertimeHours) { attendanceTableItem.LeaveHours = attendanceTableItem.PaidLeaveHours = attendanceTableItem.AvailableHours - totalOvertimeHours; } else { attendanceTableItem.LeaveHours = attendanceTableItem.PaidLeaveHours = 0; } } attendanceTableItem.WorkPaidHours = 0; } #endregion } unitOfWork.AddObject(typeof(Att_AttendanceTableItem), attendanceTableItem); } #endregion #region Tính toán lại phép năm và phép ốm trong kỳ var annualLeaveDetail = listAnnualDetailByProfile.Where(d => d.Type == AnnualLeaveDetailType.E_ANNUAL_LEAVE.ToString()).FirstOrDefault(); var sickLeaveDetail = listAnnualDetailByProfile.Where(d => d.Type == AnnualLeaveDetailType.E_SICK_LEAVE.ToString()).FirstOrDefault(); var preAttendanceTable = listPreAttendanceTableByProfile.Where(d => d.ProfileID == profileID).FirstOrDefault(); attendanceTable.AnlDayTaken = anlDayTaken; attendanceTable.SickDayTaken = sickDayTaken; if (preAttendanceTable != null) { if (annualLeaveDetail != null && annualLeaveDetail.MonthYear.HasValue && annualLeaveDetail.MonthYear.Value.Date == monthYear.Date) { attendanceTable.AnlDayAdjacent = anlDayTaken; } else { //VinhTran - 0030581 - AnlDayAdjacent là số ngày đã nghỉ tính tới đầu tháng đang tính công attendanceTable.AnlDayAdjacent = preAttendanceTable.AnlDayAdjacent.GetDouble() + anlDayTaken; } if (sickLeaveDetail != null && sickLeaveDetail.MonthYear.HasValue && sickLeaveDetail.MonthYear.Value.Date == monthYear.Date) { attendanceTable.SickDayAdjacent = sickDayTaken; } else { //VinhTran - 0030581 - AnlDayAdjacent là số ngày đã nghỉ tính tới đầu tháng đang tính công attendanceTable.SickDayAdjacent = preAttendanceTable.SickDayAdjacent.GetDouble() + sickDayTaken; } } else { attendanceTable.AnlDayAdjacent = anlDayTaken; attendanceTable.SickDayAdjacent = sickDayTaken; } if (annualLeaveDetail != null && annualLeaveDetail.MonthYear.HasValue) { attendanceTable.TotalAnlDayAvailable = annualLeaveDetail.Available.Get_Double(); attendanceTable.AnlDayAvailable = attendanceTable.TotalAnlDayAvailable.GetDouble() - attendanceTable.AnlDayAdjacent.GetDouble(); } else if (preAttendanceTable != null) { attendanceTable.AnlDayAvailable = preAttendanceTable.AnlDayAvailable - attendanceTable.AnlDayTaken; } if (sickLeaveDetail != null && sickLeaveDetail.MonthYear.HasValue) { attendanceTable.TotalSickDayAvailable = sickLeaveDetail.Available.Get_Double(); attendanceTable.SickDayAvailable = attendanceTable.TotalSickDayAvailable.GetDouble() - attendanceTable.SickDayAdjacent.GetDouble(); } else if (preAttendanceTable != null) { //tháng 7: còn 13, liền kề 1, hiện tại 1 => tháng 8: liền kề 2, hiện tại 1, còn 12 attendanceTable.SickDayAvailable = preAttendanceTable.SickDayAvailable.GetDouble() - attendanceTable.SickDayTaken.GetDouble(); } #endregion #region Tính toán lại phép bù trong kỳ foreach (var leaveDayByProfile in listLeaveDayByProfile) { if (leaveDayByProfile != null) { var dateStart = leaveDayByProfile.DateStart; var dateEnd = leaveDayByProfile.DateEnd; if (leaveDayByProfile.DateOvertimeOff.HasValue) { dateStart = leaveDayByProfile.DateOvertimeOff.Value; dateEnd = leaveDayByProfile.DateOvertimeOff.Value; } for (DateTime date = dateStart.Date; date <= dateEnd; date = date.AddDays(1)) { double leaveHours = 0D; double leaveDays = 0D; double standardWorkHours = 0; var leaveDayType = listLeaveDayType.Where(d => d.ID == leaveDayByProfile.LeaveDayTypeID).FirstOrDefault(); var attendanceTableItem = attendanceTable.Att_AttendanceTableItem.Where(d => d.WorkDate == date).FirstOrDefault(); if (attendanceTableItem!=null) standardWorkHours = attendanceTableItem.udStandardWorkHours; if (leaveDayByProfile.DurationType == LeaveDayDurationType.E_FULLSHIFT.ToString()) { //Lấy giờ nghỉ của ngày đang xét dựa vào ca làm việc leaveHours = standardWorkHours; leaveDays = 1;//Nghỉ full shift } else { leaveHours = leaveDayByProfile.LeaveHours.GetDouble(); leaveDays = leaveDayByProfile.LeaveDays.GetDouble(); } leaveHours = leaveHours > standardWorkHours ? standardWorkHours : leaveHours; leaveDays = leaveDays > 1 ? 1 : leaveDays;//Tối đa là nghỉ 1 ngày if (leaveDayType != null && leaveDays > 0) { if (leaveDayType.Code == LeavedayTypeCode.CPS.ToString() || leaveDayType.Code == LeavedayTypeCode.OCPS.ToString()) { if ((leaveDayByProfile.DateOvertimeOff.HasValue && leaveDayByProfile.DateStart > attendanceTo) || date > attendanceTo) { //Nghỉ CO tháng sau => coEndPeriod coEndPeriod += leaveDays; } else if (date >= attendanceFrom && date <= attendanceTo) { //Nghỉ CO trong tháng => coBeginPeriod coBeginPeriod += leaveDays; } } } } } } attendanceTable.COBeginPeriod = coBeginPeriod; attendanceTable.COEndPeriod = coEndPeriod; #endregion #region Cập nhật Att_AttendanceTable sau khi tính xong #region Sum type HDTJob var _type4 = attendanceTable.Att_AttendanceTableItem.Where(d => d.HDTJobType == EnumDropDown.HDTJobType.E_TYPE4.ToString()); var _type5 = attendanceTable.Att_AttendanceTableItem.Where(d => d.HDTJobType == EnumDropDown.HDTJobType.E_TYPE5.ToString()); attendanceTable.HDTJobType1 = EnumDropDown.HDTJobType.E_TYPE4.ToString(); attendanceTable.HDTJobType2 = EnumDropDown.HDTJobType.E_TYPE5.ToString(); attendanceTable.HDTJobDayCount1 = _type4 != null ? _type4.Count() : 0; attendanceTable.HDTJobDayCount2 = _type5 != null ? _type5.Count() : 0; #endregion attendanceTable.RealWorkDayCount = attendanceTable.Att_AttendanceTableItem.Where(d => d.udWorkHours > 0).Sum(d => (d.WorkPaidHours + d.LateEarlyMinutes / 60.0) / (d.udStandardWorkHours * d.udStandardWorkHours / d.udWorkHours)); attendanceTable.NightShiftHours = attendanceTable.Att_AttendanceTableItem.Where(d => d.DutyCode == DutyCode.E_ON.ToString()).Sum(d => d.NightShiftHours); attendanceTable.OTNightShiftHours = attendanceTable.Att_AttendanceTableItem.Where(d => d.DutyCode == DutyCode.E_ON.ToString()).Sum(d => d.OTNightShiftHours.GetDouble()); attendanceTable.LateEarlyDeductionHours += attendanceTable.Att_AttendanceTableItem.Sum(d => d.LateEarlyMinutes) / 60.0; attendanceTable.UnPaidLeave = attendanceTable.Att_AttendanceTableItem.Sum(d => d.UnpaidLeaveDays.GetDouble()); attendanceTable.PaidLeaveDays = attendanceTable.Att_AttendanceTableItem.Sum(d => d.PaidLeaveDays.GetDouble()); //Tính nghỉ bù attendanceTable.COBeginPeriod = coBeginPeriod; attendanceTable.COEndPeriod = coEndPeriod; //Tính số ngày công chuẩn int weekendDaysCount = attendanceTable.Att_AttendanceTableItem.Where(d => d.IsHoliday).Count(); attendanceTable.StdWorkDayCount = GetStandardWorkDays(gradeCfg, listHoliday, listShift, listMonthShiftID, monthYear, attendanceFrom, attendanceTo); attendanceTable.StdWorkDayOTCount = GetOTStandardWorkDays(weekendDaysCount, gradeCfg, listHoliday, listShift, listMonthShiftID, monthYear, attendanceFrom, attendanceTo); //Tổng số ngày được trả lương của nhân viên đang xét => ngày thực tế attendanceTable.PaidWorkDayCount = attendanceTable.RealWorkDayCount; if (gradeCfg.EDType == PayrollComputeMethod.E_SUBTRACT.ToString()) { //Số ngày công thực tế + số ngày nghỉ hưởng lương Double workAndPaidLeaveDays = attendanceTable.RealWorkDayCount; double unHiredDays = 0; double terminatedDays = 0; if (attendanceTable.Att_AttendanceTableItem.Count() > 0) { workAndPaidLeaveDays += attendanceTable.Att_AttendanceTableItem.Sum(d => d.PaidLeaveHours / d.udStandardWorkHours); } //Nếu nhân viên không vào làm hoặc nghỉ việc trong tháng và số ngày công thực tế + số ngày nghỉ hưởng lương > số ngày công tối thiểu if (((profile.DateHire.HasValue && profile.DateHire.Value.Date < attendanceFrom) || workAndPaidLeaveDays > attendanceTable.StdWorkDayCount) && ((!profile.DateQuit.HasValue || profile.DateQuit.Value.Date > attendanceTo) || workAndPaidLeaveDays > attendanceTable.StdWorkDayCount) && workAndPaidLeaveDays >= gradeCfg.MinWorkDay.Value) { //Tổng số ngày nghỉ loại 1 và loại 2 khi có trường hợp 1 ngày mà nghỉ 2 loại Double totalLeaveDays = attendanceTable.Att_AttendanceTableItem.Sum(d => (d.LeaveHours + d.ExtraLeaveHours) / d.udStandardWorkHours); if (isMidCutOffDay) { totalLeaveDays = attendanceTable.Att_AttendanceTableItem.Where(d => d.WorkDate <= midCutOffDate) .Sum(d => d.LeaveHours + d.ExtraLeaveHours / d.udStandardWorkHours);//Số ngày nghỉ không ứng công } //Cộng thêm số ngày chưa làm việc - trường hợp làm nửa ca totalLeaveDays += attendanceTable.Att_AttendanceTableItem.Sum(d => d.udNotHiredHours / d.udStandardWorkHours); if (profile.DateQuit.HasValue) { //Cộng thêm số ngày đã nghỉ việc totalLeaveDays += attendanceTable.Att_AttendanceTableItem.Sum(d => d.udTerminatedHours / d.udStandardWorkHours); } //Tính số ngày công tính lương = số ngày công chuẩn - tổng số ngày nghỉ attendanceTable.PaidWorkDayCount = attendanceTable.StdWorkDayCount - totalLeaveDays; if (attendanceTable.PaidWorkDayCount < 0) { attendanceTable.PaidWorkDayCount = 0; } } else if ((gradeCfg.IsApplySubSalaryNewQuitEmp.GetBoolean() && workAndPaidLeaveDays >= gradeCfg.MinWorkDayNewQuitEmp.GetDouble()) && ((profile.DateHire.HasValue && profile.DateHire.Value.Date >= attendanceFrom) || (profile.DateQuit.HasValue && profile.DateQuit.Value.Date <= attendanceTo))) { Double totalLeaveDays = attendanceTable.Att_AttendanceTableItem.Sum(it => (it.LeaveHours + it.ExtraLeaveHours) / it.udStandardWorkHours); Double DayNonShiftInUnEmployeeTime = 0;//Thời gian của nhân viên không có lịch làm việc trước khi vào công ty hoặc là sau khi ra khỏi công ty trong tháng if (profile.DateHire.HasValue && profile.DateHire.Value > attendanceFrom) { unHiredDays = profile.DateHire.Value.Subtract(attendanceFrom).Days; for (DateTime DateCheck = attendanceFrom; DateCheck < profile.DateHire.Value; DateCheck = DateCheck.AddDays(1)) { if (listMonthShiftID == null || !listMonthShiftID.Any(d => d.Key.Date == DateCheck.Date && d.Value != null)) { DayNonShiftInUnEmployeeTime++; } } } if (profile.DateQuit.HasValue && profile.DateQuit.Value < attendanceTo) { terminatedDays = attendanceTo.Subtract(profile.DateQuit.Value).Days + 1; for (DateTime DateCheck = profile.DateQuit.Value; DateCheck < attendanceTo; DateCheck = DateCheck.AddDays(1)) { if (listMonthShiftID == null || !listMonthShiftID.Any(d => d.Key.Date == DateCheck.Date && d.Value != null)) { DayNonShiftInUnEmployeeTime++; } } } Double paidWorkDay = attendanceTable.StdWorkDayCount - totalLeaveDays; paidWorkDay = paidWorkDay - (unHiredDays + terminatedDays - DayNonShiftInUnEmployeeTime) * gradeCfg.RateUneven.GetDouble(); attendanceTable.PaidWorkDayCount = paidWorkDay; } } #region Tính tổng thời gian theo từng loại ngày nghỉ và loại làm thêm TotalGroupByLeaveDayType(attendanceTable, attendanceTo); TotalGroupByOvertimeType(attendanceTable, attendanceTo); #endregion #region Tính tổng thời gian và làm tròn attendanceTable.TotalPaidWorkDayCount = attendanceTable.PaidWorkDayCount; attendanceTable.TotalRealWorkDayCount = attendanceTable.RealWorkDayCount; //Cấu hình làm tròng trễ sớm theo tháng if (gradeCfg != null && gradeCfg.IsLateEarlyFirstLastShiftRound == true) { attendanceTable.LateEarlyDeductionHours = Att_AttendanceLib.RoundLateEarlyMinutes(listLateEarlyRule.Where(d => d.GradeCfgID == gradeCfg.ID).ToList(), Convert.ToInt32(attendanceTable.LateEarlyDeductionHours * 60)) / 60; } #endregion #endregion return attendanceTable != null ? 1 : 0; }
/// <summary> /// Tính số ngày phép năm được cộng thêm do thâm niên theo quy định. /// </summary> /// <param name="monthYearEval"></param> /// <param name="monthYearEffect"></param> /// <param name="dateHire"></param> /// <param name="gradeCfg"></param> /// <returns></returns> public static double GetAnnualBySeniority(DateTime monthYearEval, DateTime monthYearEffect, DateTime? dateHire, Cat_GradeAttendance gradeCfg) { EnumDropDown.OptionReceive optionReceive = EnumDropDown.OptionReceive.E_FULLYEAR; if (gradeCfg != null && !string.IsNullOrWhiteSpace(gradeCfg.OptionReceive)) { if (!Enum.TryParse<EnumDropDown.OptionReceive>(gradeCfg.OptionReceive, out optionReceive)) { optionReceive = EnumDropDown.OptionReceive.E_FULLYEAR; } } return GetAnnualBySeniority(monthYearEval, monthYearEffect, dateHire, optionReceive, gradeCfg.Seniority, gradeCfg.TotalDayAnnualLeaveOnYear); }
/// <summary> /// Kiểm tra ca làm việc hàng ngày của nhân viên. /// </summary> /// <param name="profile">Nhân viên cần kiểm tra</param> /// <param name="gradeCfg">Cấu hình của chế độ lương</param> /// <param name="listRoster">Lịch làm việc của nhân viên</param> /// <param name="listWorkHistory">Quá trình công tác</param> /// <param name="dateFrom">Khoảng thời gian cần kiểm tra</param> /// <param name="dateTo">Khoảng thời gian cần kiểm tra</param> /// <returns></returns> public static Dictionary<DateTime, Cat_Shift> GetDailyShifts(Guid profileID, Cat_GradeAttendance gradeCfg, List<Att_Roster> listRoster, List<Hre_WorkHistory> listWorkHistory, DateTime dateFrom, DateTime dateTo , List<Att_RosterGroup> lstRosterGroup, List<Att_Roster> lstRosterTypeGroup) { Dictionary<DateTime, Cat_Shift> listShift = new Dictionary<DateTime, Cat_Shift>(); if (gradeCfg != null) { #region Ưu tiên ca theo roster cá nhân trước if (gradeCfg.RosterType == GradeRosterType.E_ISROSTER.ToString()) { GetDailyShifts(profileID, listRoster, dateFrom, dateTo, ref listShift, lstRosterGroup, lstRosterTypeGroup); } #endregion #region Tiếp theo ưu tiên theo lịch sử công tác if (gradeCfg.RosterType == GradeRosterType.E_ISROSTER_ORG.ToString()) { if (profileID != Guid.Empty && listWorkHistory != null) { GetDailyShifts(profileID, listWorkHistory, dateFrom, dateTo, ref listShift); } } #endregion #region Ca cấu hình mặc định được ưu tiên sau cùng if (gradeCfg.RosterType == GradeRosterType.E_ISDEFAULT.ToString()) { GetDailyShifts(gradeCfg, dateFrom, dateTo, ref listShift); } #endregion } //Loại bỏ những kết quả có shift bị null => do bị rơi vào trường hợp time-off return listShift.Where(d => d.Value != null).ToDictionary(d => d.Key, d => d.Value); }
/// <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="profile">Nhân viên muốn tính</param> /// <param name="annualLeave">Các thông số liên quan nhân viên</param> /// <returns></returns> /// <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="profile">Nhân viên muốn tính</param> /// <param name="annualLeave">Các thông số liên quan nhân viên</param> /// <returns></returns> #endregion /// <summary> /// Kiểm tra một ngày có phải là ngày làm việc không? /// </summary> /// <param name="date"></param> /// <param name="gradeCfg"></param> /// <param name="listDailyShift"></param> /// <param name="listDayOff"></param> /// <returns></returns> public static bool IsWorkDay(DateTime date, Cat_GradeAttendance gradeCfg, Dictionary<DateTime, Cat_Shift> listDailyShift, List<Cat_DayOff> listDayOff) { bool result = false; if (gradeCfg.RosterType == GradeRosterType.E_ISROSTER.ToString() || gradeCfg.RosterType == GradeRosterType.E_ISROSTER_ORG.ToString()) { result = IsWorkDay(date, listDailyShift); } else if (gradeCfg.RosterType == GradeRosterType.E_ISDEFAULT.ToString()) { result = IsWorkDay(date, gradeCfg, listDayOff); } else if (gradeCfg.RosterType == GradeRosterType.E_ISHOLIDAY.ToString()) { if (listDayOff == null || !listDayOff.Any(d => d.DateOff.Date == date.Date && d.Type == HolidayType.E_WEEKEND_HLD.ToString())) { result = true; } } return result; }
/// <summary> /// Kiểm tra ca làm việc hàng ngày của nhân viên theo cấu hình grade. /// </summary> /// <param name="gradeCfg"></param> /// <param name="dateFrom">Khoảng thời gian cần kiểm tra</param> /// <param name="dateTo">Khoảng thời gian cần kiểm tra</param> /// <returns></returns> private static void GetDailyShifts(Cat_GradeAttendance gradeCfg, DateTime dateFrom, DateTime dateTo, ref Dictionary<DateTime, Cat_Shift> listShift) { if (gradeCfg != null) { #region Grade default roster // Bản 8 ko xài hàm này //for (DateTime date = dateFrom.Date; date <= dateTo; date = date.AddDays(1)) //{ // if (!listShift.ContainsKey(date)) // { // if (date.DayOfWeek == DayOfWeek.Monday // && gradeCfg.Cat_Shift != null) // { // listShift.Add(date, gradeCfg.Cat_Shift); // } // else if (date.DayOfWeek == DayOfWeek.Tuesday // && gradeCfg.Cat_Shift1 != null) // { // listShift.Add(date, gradeCfg.Cat_Shift1); // } // else if (date.DayOfWeek == DayOfWeek.Wednesday // && gradeCfg.Cat_Shift2 != null) // { // listShift.Add(date, gradeCfg.Cat_Shift2); // } // else if (date.DayOfWeek == DayOfWeek.Thursday // && gradeCfg.Cat_Shift3 != null) // { // listShift.Add(date, gradeCfg.Cat_Shift3); // } // else if (date.DayOfWeek == DayOfWeek.Friday // && gradeCfg.Cat_Shift4 != null) // { // listShift.Add(date, gradeCfg.Cat_Shift4); // } // else if (date.DayOfWeek == DayOfWeek.Saturday // && gradeCfg.Cat_Shift5 != null) // { // listShift.Add(date, gradeCfg.Cat_Shift5); // } // else if (date.DayOfWeek == DayOfWeek.Sunday // && gradeCfg.Cat_Shift6 != null) // { // listShift.Add(date, gradeCfg.Cat_Shift6); // } // } //} #endregion } }
/// <summary> /// Lấy khoảng thời gian tính lương theo grade config. /// </summary> /// <param name="gradeCfg"></param> /// <param name="monthYear"></param> /// <param name="dateFrom"></param> /// <param name="dateTo"></param> public static void GetDuration(Cat_GradeAttendance gradeCfg, DateTime monthYear, out DateTime dateFrom, out DateTime dateTo) { int day = 1; if (gradeCfg != null) { if (gradeCfg.SalaryTimeType == EnumDropDown.SalaryTimeType.E_LASTMONTH.ToString()) { monthYear = monthYear.AddMonths(-1); } day = gradeCfg.SalaryTimeDay.Get_Integer() <= 0 ? 1 : gradeCfg.SalaryTimeDay.Get_Integer(); dateFrom = new DateTime(monthYear.Year, monthYear.Month, day); dateTo = dateFrom.AddMonths(1).AddSeconds(-1); } else { GetDuration(monthYear, out dateFrom, out dateTo); } }
public static Double GetStandardWorkDays(Cat_GradeAttendance gradeCfg, List<Cat_DayOff> listDayOff, List<Cat_Shift> listShift, Dictionary<DateTime, List<Guid?>> listMonthShifts, DateTime monthYear, DateTime dateFrom, DateTime dateTo) { Double result = 0; int holidayCount = listDayOff.Where(d => d.DateOff >= dateFrom && d.DateOff <= dateTo).Count(); if (gradeCfg.IsFixedLeave.GetBoolean()) { result = gradeCfg.LeaveWorkDayFix.GetDouble(); } else if (gradeCfg.IsActualLeave.GetBoolean()) { result = dateTo.Subtract(dateFrom).Days + 1; if (gradeCfg.LeaveWorkdayActual.HasValue) { result += gradeCfg.LeaveWorkdayActual.Value; } } else if (gradeCfg.IsRosterLeave.HasValue && gradeCfg.IsRosterLeave.Value) { if (gradeCfg.RosterType == GradeRosterType.E_ISROSTER.ToString()) { result = GetRosterStandardWorkDays(gradeCfg, listShift, listMonthShifts, dateFrom, dateTo); } else if (gradeCfg.RosterType == GradeRosterType.E_ISDEFAULT.ToString()) { result = GetGradeStandardWorkDays(gradeCfg, dateFrom, dateTo); } else if (gradeCfg.RosterType == GradeRosterType.E_ISHOLIDAY.ToString()) { int monthDayCount = dateTo.Subtract(dateFrom).Days + 1; result = monthDayCount - holidayCount; } } //else if (gradeCfg.IsFormulaLeave.HasValue && gradeCfg.IsFormulaLeave.Value) else if (gradeCfg.LeaveWorkdayFormula != null) { Formula formula = new Formula(gradeCfg.LeaveWorkdayFormula); if (gradeCfg.LeaveWorkdayFormula.Contains(Formula.FormulaConstant.DAYS_IN_MONTH_EXCLUDE_SUNDAY.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.DAYS_IN_MONTH_EXCLUDE_SUNDAY.ToString(), GetDaysInMonthExcludeSunday(gradeCfg, monthYear)); } if (gradeCfg.LeaveWorkdayFormula.Contains(Formula.FormulaConstant.DAYS_IN_MONTH_EXCLUDE_SUNDAY_HOLIDAY.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.DAYS_IN_MONTH_EXCLUDE_SUNDAY_HOLIDAY.ToString(), GetDaysInMonthExcludeSunday(gradeCfg, monthYear) - holidayCount); } if (gradeCfg.LeaveWorkdayFormula.Contains(Formula.FormulaConstant.WORKDAY_STANDARD_PER_MONTH.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.WORKDAY_STANDARD_PER_MONTH.ToString(), GetWorkdayStandardPerMonth(listDayOff, dateFrom, dateTo)); } if (gradeCfg.LeaveWorkdayFormula.Contains(Formula.FormulaConstant.D.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.D.ToString(), dateTo.Subtract(dateFrom).Days + 1); } if (gradeCfg.LeaveWorkdayFormula.Contains(Formula.FormulaConstant.H.ToString())) { formula.Parameters.Add(Formula.FormulaConstant.H.ToString(), holidayCount); } if (gradeCfg.LeaveWorkdayFormula.Contains(Formula.FormulaConstant.S.ToString())) { int sundayCount = 0; for (DateTime date = dateFrom; date <= dateTo; date = date.AddDays(1)) { if (date.DayOfWeek == DayOfWeek.Sunday) { sundayCount++; } } formula.Parameters.Add(Formula.FormulaConstant.S.ToString(), sundayCount); } if (gradeCfg.LeaveWorkdayFormula.Contains(Formula.FormulaConstant.R.ToString())) { Double count = GetRosterStandardWorkDays(gradeCfg, listShift, listMonthShifts, dateFrom, dateTo); formula.Parameters.Add(Formula.FormulaConstant.R.ToString(), count); } if (gradeCfg.LeaveWorkdayFormula.Contains(Formula.FormulaConstant.R_NOT_H.ToString())) { Double count = GetRosterSdNotHoliDays(listMonthShifts, listDayOff, dateFrom, dateTo); formula.Parameters.Add(Formula.FormulaConstant.R_NOT_H.ToString(), count); } if (gradeCfg.LeaveWorkdayFormula.Contains(Formula.FormulaConstant.SAT.ToString())) { int satdayCount = 0; for (DateTime date = dateFrom; date <= dateTo; date = date.AddDays(1)) { if (date.DayOfWeek == DayOfWeek.Saturday) { satdayCount++; } } formula.Parameters.Add(Formula.FormulaConstant.SAT.ToString(), satdayCount); } if (gradeCfg.LeaveWorkdayFormula.Contains(Formula.FormulaConstant.SHIFT_COUNT.ToString())) { int ShiftCount = 0; for (DateTime date = dateFrom; date <= dateTo; date = date.AddDays(1)) { if (listMonthShifts.ContainsKey(date) && listMonthShifts[date] != null) { ShiftCount++; } } formula.Parameters.Add(Formula.FormulaConstant.SHIFT_COUNT.ToString(), ShiftCount); } result = Convert.ToDouble(formula.Evaluate()); } return result; }