Пример #1
0
        /// <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;
        }
Пример #2
0
        /// <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;
        }
Пример #3
0
        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;
        }
Пример #4
0
        /// <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;
        }
Пример #5
0
        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;
        }
Пример #6
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="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);
 }
Пример #7
0
        /// <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;
        }
Пример #8
0
 /// <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;
 }
Пример #9
0
 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;
 }
Пример #10
0
        /// <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;
        }
Пример #11
0
        /// <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;
        }
Пример #12
0
        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;
        }
Пример #13
0
        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;
        }
Пример #14
0
        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;
        }
Пример #15
0
        /// <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;
        }
Пример #16
0
        /// <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);
            }
        }
Пример #17
0
        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;
            }

        }
Пример #18
0
        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;
        }
Пример #19
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);
        }
Пример #20
0
        /// <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);
        }
Пример #21
0
        /// <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;
        }
Пример #22
0
        /// <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
            }
        }
Пример #23
0
        /// <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);
            }
        }
Пример #24
0
        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;
        }