private List<Att_AnnualDetail> AnalyzeAnnualSickPerProfile(Hre_ProfileEntity Profile, List<Cat_GradeAttendance> lstGradeCfg, List<Att_Grade> lstGrade,
            DateTime BeginYear, DateTime EndYear, List<Att_LeaveDay> lstLeaveSick, List<Att_AnnualDetail> lstAnnualDetailInDB, Att_AnnualLeave AnnualLeave,
            List<Att_Roster> lstRosterInYear, List<Att_RosterGroup> lstRosterGroup, List<Hre_WorkHistory> lstWorkHistory, List<Cat_DayOff> lstDayOff,
            bool IsFrom1To31, List<Cat_Shift> shifts)
        {
            List<Att_AnnualDetail> lstResult = new List<Att_AnnualDetail>();
            double leaveBeginYearToMonth = 0;
            double leaveBeginYearToMonth_Init = 0;
            string E_ROSTERGROUP = RosterType.E_ROSTERGROUP.ToString();
            List<Att_Roster> lstRoster_byProfile = lstRosterInYear.Where(m => m.ProfileID == Profile.ID && m.Type != E_ROSTERGROUP).ToList();
            List<Att_Roster> lstRosterTypeGroup = lstRosterInYear.Where(m => m.ProfileID == Profile.ID && m.Type == E_ROSTERGROUP).ToList();

            for (DateTime Month = BeginYear; Month <= EndYear; Month = Month.AddMonths(1))
            {
                var gradeByProfileByTime = lstGrade.Where(m => m.ProfileID == Profile.ID && m.MonthStart <= Month).OrderByDescending(m => m.MonthStart).FirstOrDefault();
                if (gradeByProfileByTime == null)
                    continue;
                var GradeCfg = lstGradeCfg.Where(m => m.ID == gradeByProfileByTime.GradeAttendanceID).FirstOrDefault();
                if (GradeCfg == null)
                    continue;

                DateTime BeginMonth = Month;
                DateTime EndMonth = BeginMonth.AddMonths(1).AddMinutes(-1);
                if (!IsFrom1To31)
                {
                    Att_AttendanceServices.GetRangeMaxMinGrade(new List<Cat_GradeAttendance>() { GradeCfg }, Month, out BeginMonth, out EndMonth);
                }
                double Availale = AnnualLeave == null ? 0 : AnnualLeave.InitSickValue;
                double LeaveInMonth = 0;
                List<Att_LeaveDay> lstSickInMonth = lstLeaveSick.Where(m => m.ProfileID == Profile.ID && m.DateStart <= EndMonth && m.DateEnd >= BeginMonth).ToList();

                var listRosterEntity = lstRoster_byProfile.Select(d => new Att_RosterEntity
                {
                    ID = d.ID,
                    ProfileID = d.ProfileID,
                    RosterGroupName = d.RosterGroupName,
                    Type = d.Type,
                    Status = d.Status,
                    DateEnd = d.DateEnd,
                    DateStart = d.DateStart,
                    MonShiftID = d.MonShiftID,
                    TueShiftID = d.TueShiftID,
                    WedShiftID = d.WedShiftID,
                    ThuShiftID = d.ThuShiftID,
                    FriShiftID = d.FriShiftID,
                    SatShiftID = d.SatShiftID,
                    SunShiftID = d.SunShiftID,
                    MonShift2ID = d.MonShiftID,
                    TueShift2ID = d.TueShift2ID,
                    WedShift2ID = d.WedShift2ID,
                    ThuShift2ID = d.ThuShift2ID,
                    FriShift2ID = d.FriShift2ID,
                    SatShift2ID = d.SatShift2ID,
                    SunShift2ID = d.SunShift2ID
                }).ToList();

                var listRosterGroupEntity = lstRosterGroup.Select(d => new Att_RosterGroupEntity
                {
                    ID = d.ID,
                    DateEnd = d.DateEnd,
                    DateStart = d.DateStart,
                    MonShiftID = d.MonShiftID,
                    TueShiftID = d.TueShiftID,
                    WedShiftID = d.WedShiftID,
                    ThuShiftID = d.ThuShiftID,
                    FriShiftID = d.FriShiftID,
                    SatShiftID = d.SatShiftID,
                    SunShiftID = d.SunShiftID,
                    RosterGroupName = d.RosterGroupName
                }).ToList();

                foreach (var item in lstSickInMonth)
                {
                    if (item.DateStart >= BeginMonth && item.DateEnd <= EndMonth)
                    {
                        //Chi cần lấy TotalDuration hoặc lấy giờ rồi lấy ca
                        if (item.DurationType == LeaveDayDurationType.E_FULLSHIFT.ToString())
                        {
                            LeaveInMonth += item.TotalDuration ?? 0;
                        }
                        else
                        {

                            //Lấy ra ca làm việc 
                            DateTime DateBeginLeave = item.DateStart.Date;
                            DateTime DateEndLeave = item.DateEnd.Date;

                            Dictionary<DateTime, Cat_Shift> dicShift = Att_AttendanceLib.GetDailyShifts(Profile != null ? Profile.ID : Guid.Empty, DateBeginLeave, DateEndLeave, listRosterEntity, listRosterGroupEntity, shifts);

                            if (dicShift != null && dicShift.ContainsKey(DateBeginLeave))
                            {
                                Cat_Shift shift = dicShift[DateBeginLeave];
                                if (shift != null)
                                {
                                    double HourWorkday = 8;
                                    if (shift.WorkHours != null && shift.WorkHours != 0)
                                    {
                                        HourWorkday = shift.WorkHours ?? 8;
                                    }
                                    LeaveInMonth += item.Duration / HourWorkday;
                                }
                            }
                        }
                    }
                    else
                    {
                        DateTime DateBegin = BeginMonth > item.DateStart ? BeginMonth : item.DateStart;
                        DateTime DateEnd = EndMonth < item.DateEnd ? BeginMonth : item.DateEnd;
                        Dictionary<DateTime, Cat_Shift> dicShift = Att_AttendanceLib.GetDailyShifts(Profile != null ? Profile.ID : Guid.Empty, DateBegin, DateEnd, listRosterEntity, listRosterGroupEntity, shifts);
                        for (DateTime dateCheck = DateBegin; dateCheck <= DateEnd; dateCheck = dateCheck.AddDays(1))
                        {
                            if (Att_WorkDayHelper.IsWorkDay(dateCheck, GradeCfg, dicShift, lstDayOff) && !lstDayOff.Any(m => m.DateOff == dateCheck))
                            {
                                LeaveInMonth++;
                            }
                        }
                    }
                }
                Att_AnnualDetail AnnualDetail = lstAnnualDetailInDB.Where(m => m.ProfileID == Profile.ID && m.MonthYear == Month).FirstOrDefault();
                if (AnnualDetail == null)
                {
                    AnnualDetail = new Att_AnnualDetail();
                }
                if (Profile.DateQuit != null)
                {
                    DateTime MonthQuit = Profile.DateQuit.Value.Day >= 15 ? Profile.DateQuit.Value.AddMonths(1) : Profile.DateQuit.Value;
                    MonthQuit = new DateTime(MonthQuit.Year, MonthQuit.Month, 1);
                    if (Month >= MonthQuit)
                    {
                        AnnualDetail.IsDelete = true;
                    }
                }
                AnnualDetail.Available = Availale;
                AnnualDetail.InitAvailable = AnnualLeave == null ? 0 : AnnualLeave.InitSickValue;
                AnnualDetail.ProfileID = Profile.ID;
                AnnualDetail.Year = BeginYear.Year;
                AnnualDetail.MonthYear = Month;
                AnnualDetail.MonthBeginInYear = MonthStartAnl; //todo: Phần tử này để trong cấu hình chung
                if (AnnualLeave != null && AnnualLeave.MonthResetAnlOfBeforeYear != null)
                {
                    AnnualDetail.MonthResetInitAvailable = AnnualLeave.MonthResetAnlOfBeforeYear.Value;//todo: MonthReset Này để trong chế độ lương
                }
                else
                {
                    AnnualDetail.MonthResetInitAvailable = 12;//todo: MonthReset Này để trong chế độ lương
                }
                AnnualDetail.MonthStartProfile = AnnualLeave == null ? 1 : AnnualLeave.MonthStart;
                if (AnnualDetail.MonthResetInitAvailable != null && AnnualDetail.MonthResetInitAvailable != 12 && AnnualDetail.Year != null)
                {
                    DateTime MonthReset = new DateTime(AnnualDetail.Year.Value, AnnualDetail.MonthResetInitAvailable.Value, 1);
                    AnnualDetail.IsHaveResetInitAvailable = true;
                    if (Month <= MonthReset) //Trong những tháng có
                    {
                        double delta = leaveBeginYearToMonth_Init + LeaveInMonth - AnnualDetail.InitAvailable.Value;
                        if (delta > 0)
                        {
                            AnnualDetail.TotalLeaveBefFromInitAvailable = leaveBeginYearToMonth_Init;
                            AnnualDetail.LeaveInMonthFromInitAvailable = LeaveInMonth - delta;
                            AnnualDetail.LeaveInMonth = delta;
                            AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth;
                            leaveBeginYearToMonth += delta;
                            leaveBeginYearToMonth_Init += LeaveInMonth - delta;
                        }
                        else
                        {
                            AnnualDetail.TotalLeaveBefFromInitAvailable = leaveBeginYearToMonth_Init;
                            AnnualDetail.LeaveInMonthFromInitAvailable = LeaveInMonth;
                            AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth;
                            AnnualDetail.LeaveInMonth = 0;
                            leaveBeginYearToMonth_Init += LeaveInMonth;
                        }
                    }
                    else //sau những tháng kho có
                    {
                        AnnualDetail.InitAvailable = 0;
                        AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth;
                        AnnualDetail.LeaveInMonth = LeaveInMonth;
                        leaveBeginYearToMonth += LeaveInMonth;
                    }
                }
                else //Bình thường
                {
                    AnnualDetail.IsHaveResetInitAvailable = false;
                    AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth;
                    AnnualDetail.LeaveInMonth = LeaveInMonth;
                    leaveBeginYearToMonth += LeaveInMonth;
                }
                double remain = (AnnualDetail.Available ?? 0) + (AnnualDetail.InitAvailable ?? 0) - (AnnualDetail.TotalLeaveBefFromInitAvailable ?? 0) - (AnnualDetail.LeaveInMonthFromInitAvailable ?? 0) - (AnnualDetail.TotalLeaveBef ?? 0) - (AnnualDetail.LeaveInMonth ?? 0);
                AnnualDetail.Remain = remain;
                AnnualDetail.Type = AnnualLeaveDetailType.E_SICK_LEAVE.ToString();
                lstResult.Add(AnnualDetail);
            }
            return lstResult;

        }
Exemple #2
0
        ///// <summary>
        ///// Lấy toàn bộ data
        ///// </summary>
        ///// <returns></returns>
        //public IQueryable<Att_AnnualLeave> Get()
        //{
        //    using (var context = new VnrHrmDataContext())
        //    {
        //        var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
        //        var repo = new Att_AnnualLeaveRepository(unitOfWork);
        //        return repo.Get().Where(i => i.IsDelete == null);
        //    }
        //}

        ///// <summary>
        ///// Lấy dữ liệu theo Id
        ///// </summary>
        ///// <param name="id"></param>
        ///// <returns></returns>
        //public Att_AnnualLeaveEntity Get(int id)
        //{
        //    using (var context = new VnrHrmDataContext())
        //    {
        //        var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
        //        var repo = new Att_AnnualLeaveRepository(unitOfWork);
        //        var data = repo.GetAnnualLeaveById(id);
        //        if (data.IsDelete == true) data = null;
        //        return data;
        //    }
        //}

        //public List<Att_AnnualLeaveEntity> GetAnnualLeaveByIds(string selectedIds)
        //{
        //    using (var context = new VnrHrmDataContext())
        //    {
        //        var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
        //        var repo = new Att_AnnualLeaveRepository(unitOfWork);
        //        return repo.GetAnnualLeaveByIds(selectedIds);
        //    }
        //}

        ///// <summary>
        ///// Thêm mới một record
        ///// </summary>
        ///// <param name="cat"></param>
        ///// <returns></returns>
        //public bool Add(Att_AnnualLeave model)
        //{
        //    using (var context = new VnrHrmDataContext())
        //    {
        //        var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
        //        var repo = new Att_AnnualLeaveRepository(unitOfWork);
        //        try
        //        {
        //            repo.Add(model);
        //            repo.SaveChanges();
        //            return true;
        //        }
        //        catch
        //        {
        //            return false;
        //        }
        //    }
        //}

        ///// <summary>
        ///// Edit một record
        ///// </summary>
        ///// <param name="cat"></param>
        ///// <returns></returns>
        //public bool Edit(Att_AnnualLeave model)
        //{
        //    using (var context = new VnrHrmDataContext())
        //    {
        //        var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
        //        var repo = new Att_AnnualLeaveRepository(unitOfWork);
        //        try
        //        {
        //            repo.Edit(model);
        //            repo.SaveChanges();
        //            return true;
        //        }
        //        catch
        //        {
        //            return false;
        //        }

        //    }
        //}

        ///// <summary>
        ///// Remove 1 record là chuyển trạng thái IsDelete=true
        ///// </summary>
        ///// <param name="id"></param>
        ///// <returns></returns>
        //public bool Remove(int id)
        //{
        //    using (var context = new VnrHrmDataContext())
        //    {
        //        var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
        //        var repo = new Att_AnnualLeaveRepository(unitOfWork);
        //        var data = repo.GetById(id);
        //        try
        //        {
        //            repo.Remove(data);
        //            repo.SaveChanges();
        //            return true;
        //        }
        //        catch
        //        {
        //            return false;
        //        }

        //    }
        //}

        ///// <summary>
        ///// Delete 1 record là xóa luôn record khỏi database
        ///// </summary>
        ///// <param name="id"></param>
        ///// <returns></returns>
        //public bool Delete(int id)
        //{
        //    using (var context = new VnrHrmDataContext())
        //    {
        //        var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
        //        var repo = new Att_AnnualLeaveRepository(unitOfWork);
        //        var data = repo.GetById(id);
        //        try
        //        {
        //            repo.Delete(data);
        //            repo.SaveChanges();
        //            return true;
        //        }
        //        catch
        //        {
        //            return false;
        //        }

        //    }
        //}

        //#region Store Procedure

        //#region Danh sách

        ///// <summary>
        ///// Lấy danh sách dữ liệu AnnualLeaves [Tung.Ly - 2014/05/09]
        ///// </summary>
        ///// <returns></returns>
        //public IQueryable<Att_AnnualLeaveEntity> GetAnnualLeaves(ListQueryModel model)
        //{
        //    using (var context = new VnrHrmDataContext())
        //    {
        //        var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
        //        IAtt_AnnualLeaveRepository repo = new Att_AnnualLeaveRepository(unitOfWork);
        //        var rs = repo.GetAnnualLeaves(model);
        //        return rs;
        //    }
        //}

        //#endregion

        //#region Chi tiet

        ///// <summary>
        ///// Lấy dữ liệu AnnualLeave theo Id [Tung.Ly - 2014/05/09]
        ///// </summary>
        ///// <param name="annualLeaveId"></param>
        ///// <returns></returns>
        //public Att_AnnualLeaveEntity GetAnnualLeaveById(int annualLeaveId)
        //{
        //    using (var context = new VnrHrmDataContext())
        //    {
        //        var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
        //        IAtt_AnnualLeaveRepository repo = new Att_AnnualLeaveRepository(unitOfWork);
        //        var data = repo.GetAnnualLeaveById(annualLeaveId);
        //        return data;
        //    }
        //}

        //#endregion

        //#endregion
        #endregion

        #region thanh toán phép năm đầu kỳ

        public void SetAnnualLeaveBeginYear(List<Guid> lstProfileIDs, double? limitMaximum, int Year, int? MonthResetANL, Guid? AllowanceTypeID, Guid? CuttOffDurationID)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoAtt_AnnualLeave = new CustomBaseRepository<Att_AnnualLeave>(unitOfWork);
                var repoAtt_AnnualDetail = new CustomBaseRepository<Att_AnnualDetail>(unitOfWork);
                var repoSal_UnusualAllowance = new CustomBaseRepository<Sal_UnusualAllowance>(unitOfWork);
                var repoAtt_CutOffDuration = new CustomBaseRepository<Att_CutOffDuration>(unitOfWork);
                //nếu có rồi thì chỉ cần Update
                //Nếu chưa có thì tạo mới
                Att_CutOffDuration CutOffDuration = new Att_CutOffDuration();
                if (CuttOffDurationID != null)
                {
                    CutOffDuration = repoAtt_CutOffDuration.FindBy(m => m.ID == CuttOffDurationID).FirstOrDefault();
                }


                int LastYear = Year - 1;
                DateTime? MaxTime = repoAtt_AnnualDetail.FindBy(m => m.IsDelete != null && m.Year == LastYear).OrderByDescending(m => m.MonthYear).Select(m => m.MonthYear).FirstOrDefault();
                List<Att_AnnualDetail> lstAnnualDetail = new List<Att_AnnualDetail>();
                if (MaxTime != null)
                {
                    lstAnnualDetail = repoAtt_AnnualDetail.FindBy(m => m.MonthYear == MaxTime
                        && m.ProfileID != null
                        && lstProfileIDs.Contains(m.ProfileID.Value)).ToList();
                }
                var lstAnnualLeaveInDB = repoAtt_AnnualLeave.FindBy(m => m.IsDelete == null && m.Year == Year && lstProfileIDs.Contains(m.ProfileID)).ToList();


                foreach (var ProfileID in lstProfileIDs)
                {
                    Att_AnnualLeave AnnualLeaveByProfile = lstAnnualLeaveInDB.Where(m => m.ProfileID == ProfileID).FirstOrDefault();
                    bool IsNew = false;
                    if (AnnualLeaveByProfile == null)
                    {
                        IsNew = true;
                        AnnualLeaveByProfile = new Att_AnnualLeave();
                        AnnualLeaveByProfile.ID = Guid.NewGuid();
                        AnnualLeaveByProfile.ProfileID = ProfileID;
                        AnnualLeaveByProfile.Year = Year;
                        AnnualLeaveByProfile.MonthStart = 1;

                    }
                    AnnualLeaveByProfile.MonthResetAnlOfBeforeYear = MonthResetANL;
                    double RemainLastYear = lstAnnualDetail.Where(m => m.ProfileID == ProfileID).Select(m => m.Remain ?? 0).FirstOrDefault();
                    if (limitMaximum != null)
                    {
                        AnnualLeaveByProfile.InitAnlValue = RemainLastYear > limitMaximum.Value ? limitMaximum.Value : RemainLastYear;
                        AnnualLeaveByProfile.SurplusAnllastYear = RemainLastYear > limitMaximum ? RemainLastYear - limitMaximum : 0;
                        if (CutOffDuration.ID != null && CutOffDuration.ID != Guid.Empty && AllowanceTypeID != null)
                        {
                            Sal_UnusualAllowance UnusualAllowance = new Sal_UnusualAllowance();
                            UnusualAllowance.ProfileID = ProfileID;
                            UnusualAllowance.MonthStart = CutOffDuration.DateStart;
                            UnusualAllowance.MonthEnd = CutOffDuration.DateEnd;
                            UnusualAllowance.UnusualEDTypeID = AllowanceTypeID;
                            UnusualAllowance.Amount = AnnualLeaveByProfile.SurplusAnllastYear;
                            repoSal_UnusualAllowance.Add(UnusualAllowance);
                        }
                    }
                    else
                    {
                        AnnualLeaveByProfile.InitAnlValue = RemainLastYear;
                        AnnualLeaveByProfile.SurplusAnllastYear = 0;
                    }
                    //Sửa lại theo phần tử mới mà Sơn build
                    if (IsNew)
                    {
                        repoAtt_AnnualLeave.Add(AnnualLeaveByProfile);
                    }
                    else
                    {
                        repoAtt_AnnualLeave.Edit(AnnualLeaveByProfile);
                    }
                }
                repoAtt_AnnualLeave.SaveChanges();
                repoSal_UnusualAllowance.SaveChanges();
            }
        }
Exemple #3
0
        public void SetSickLeaveBeginYear(List<Guid> lstProfileIDs, double? limitMaximum, int Year)
        {
            //Đối với phép ốm thì tạm thời tính từ đầu năm đến cuối năm
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoAtt_AnnualLeave = new CustomBaseRepository<Att_AnnualLeave>(unitOfWork);
                var repoCat_LeaveDayType = new CustomBaseRepository<Cat_LeaveDayType>(unitOfWork);
                var repoAtt_LeaveDay = new CustomBaseRepository<Att_LeaveDay>(unitOfWork);
                int LastYear = Year - 1;
                DateTime beginLastYear = new DateTime(LastYear, 1, 1);
                DateTime endLastYear = beginLastYear.AddYears(1).AddMinutes(-1);
                List<Guid> SickLeaveType = repoCat_LeaveDayType.FindBy(m => m.IsDelete == null && m.Code == "SICK").Select(m => m.ID).ToList();
                string Approve = LeaveDayStatus.E_APPROVED.ToString();
                var lstLeaveDay = repoAtt_LeaveDay.FindBy(m =>
                    m.IsDelete == null
                    && m.Status == Approve
                    && m.DateStart < endLastYear
                    && m.DateEnd >= beginLastYear
                    && SickLeaveType.Contains(m.LeaveDayTypeID)
                    && lstProfileIDs.Contains(m.ProfileID)).Select(m => new { m.ProfileID, m.TotalDuration }).ToList();

                List<Att_AnnualLeave> lstAnnualLeaveInDB = repoAtt_AnnualLeave.FindBy(m => m.IsDelete == null && (m.Year == Year || m.Year == LastYear) && lstProfileIDs.Contains(m.ProfileID)).ToList();

                foreach (var ProfileID in lstProfileIDs)
                {
                    Att_AnnualLeave AnnualLeaveByProfile = lstAnnualLeaveInDB.Where(m => m.ProfileID == ProfileID && m.Year == Year).FirstOrDefault();
                    Att_AnnualLeave AnnualLeaveByProfile_Last = lstAnnualLeaveInDB.Where(m => m.ProfileID == ProfileID && m.Year == LastYear).FirstOrDefault();
                    bool IsNew = false;
                    if (AnnualLeaveByProfile == null)
                    {
                        IsNew = true;
                        AnnualLeaveByProfile = new Att_AnnualLeave();
                        AnnualLeaveByProfile.ID = Guid.NewGuid();
                        AnnualLeaveByProfile.ProfileID = ProfileID;
                        AnnualLeaveByProfile.Year = Year;
                        AnnualLeaveByProfile.MonthStart = 1;
                    }

                    double InitLastYear = 0;
                    if (AnnualLeaveByProfile_Last != null)
                        InitLastYear = AnnualLeaveByProfile_Last.InitSickValue;
                    double remainLastYear = InitLastYear - lstLeaveDay.Where(m => m.ProfileID == ProfileID).Sum(m => m.TotalDuration ?? 0);
                    if (limitMaximum != null)
                    {
                        AnnualLeaveByProfile.InitSickValue = remainLastYear > limitMaximum.Value ? limitMaximum.Value : remainLastYear;
                        AnnualLeaveByProfile.SurplusSicklastYear = remainLastYear > limitMaximum ? remainLastYear - limitMaximum : 0;
                    }
                    else
                    {
                        AnnualLeaveByProfile.InitSickValue = remainLastYear;
                        AnnualLeaveByProfile.SurplusSicklastYear = 0;
                    }
                    if (IsNew)
                    {
                        repoAtt_AnnualLeave.Add(AnnualLeaveByProfile);
                    }
                    else
                    {
                        repoAtt_AnnualLeave.Edit(AnnualLeaveByProfile);
                    }
                }
                repoAtt_AnnualLeave.SaveChanges();
            }
        }
        /// <summary>
        /// Hàm tính toán Phép năm dành cho từng nhân viên
        /// </summary>
        /// <param name="Profile">Nhân Viên</param>
        /// <param name="lstGradeCfg">Ds Chế Độ lương</param>
        /// <param name="lstGrade">Ds Grade của Nhân viên</param>
        /// <param name="BeginYear">Ngày bắt đầu của năm</param>
        /// <param name="EndYear">Ngày Kết Thúc Của Năm</param>
        /// <param name="lstLeaveAnl">Ds nghỉ phép năm</param>
        /// <param name="lstAnnualDetailInDB">Ds AnnualDetail trong DB</param>
        /// <param name="AnnualLeave">AnnualLeave</param>
        /// <param name="lstRosterInYear">Ds Roster</param>
        /// <param name="lstRosterGroup">Ds RosterGroup</param>
        /// <param name="lstWorkHistory">Ds WorkingHistory</param>
        /// <param name="lstDayOff">Ds Ngày Nghỉ Lễ </param>
        /// <returns></returns>
        private List<Att_AnnualDetail> AnalyzeAnnualDetailPerProfile(Hre_ProfileMultiField Profile, List<Cat_GradeAttendance>
            lstGradeCfg, List<Att_Grade> lstGrade, DateTime BeginYear, DateTime EndYear, List<Att_LeaveDayInfo> lstLeaveAnl,
            List<Att_AnnualDetail> lstAnnualDetailInDB, Att_AnnualLeave AnnualLeave, List<Att_RosterInfo> lstRosterInYearIn,
            List<Att_RosterGroup> lstRosterGroup, List<Cat_DayOff> lstDayOff,
            bool IsFrom1To31, Cat_Position Position, List<Sys_AllSetting> lstAllSetting, List<Hre_HDTJob> lstHDTJob, out List<Att_AnnualDetail> AnalyzeAnnualDetailPerProfile_Update, string userLogin)
        {
            AnalyzeAnnualDetailPerProfile_Update = new List<Att_AnnualDetail>();
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoAtt_Roster = new CustomBaseRepository<Att_Roster>(unitOfWork);
                var repoCat_Shift = new Cat_ShiftRepository(unitOfWork);
                var shifts = repoCat_Shift.FindBy(s => s.IsDelete == null).ToList();

                var lstRosterID = lstRosterInYearIn.Select(s => s.ID).ToList();
                var lstRosterInYear = repoAtt_Roster.FindBy(s => lstRosterID.Contains(s.ID)).ToList();

                List<Att_AnnualDetail> lstResult = new List<Att_AnnualDetail>();
                double leaveBeginYearToMonth = 0;
                double leaveBeginYearToMonth_Init = 0;
                string E_ROSTERGROUP = RosterType.E_ROSTERGROUP.ToString();
                List<Att_Roster> lstRoster_byProfile = lstRosterInYear.Where(m => m.ProfileID == Profile.ID && m.Type != E_ROSTERGROUP).ToList();
                List<Att_Roster> lstRosterTypeGroup = lstRosterInYear.Where(m => m.ProfileID == Profile.ID && m.Type == E_ROSTERGROUP).ToList();

                for (DateTime Month = BeginYear; Month <= EndYear; Month = Month.AddMonths(1))
                {
                    var gradeByProfileByTime = lstGrade.Where(m => m.ProfileID == Profile.ID && m.MonthStart <= Month).OrderByDescending(m => m.MonthStart).FirstOrDefault();
                    if (gradeByProfileByTime == null)
                        continue;
                    var GradeCfg = lstGradeCfg.Where(m => m.ID == gradeByProfileByTime.GradeAttendanceID).FirstOrDefault();
                    if (GradeCfg == null)
                        continue;

                    DateTime BeginMonth = Month;
                    DateTime EndMonth = BeginMonth.AddMonths(1).AddMinutes(-1);
                    if (!IsFrom1To31)
                    {
                        Att_AttendanceServices.GetRangeMaxMinGrade(new List<Cat_GradeAttendance>() { GradeCfg }, Month, out BeginMonth, out EndMonth);
                    }

                    int AnnualLeaveMonthStart = AnnualLeave != null ? AnnualLeave.MonthStart : 1;
                    double AnnualLeaveInitAnlValue = AnnualLeave != null ? AnnualLeave.InitAnlValue : 0;

                    double Availale = Att_AttendanceLib.GetAnnualLeaveReceive(BeginYear.Year, Month, GradeCfg, Profile.DateHire,
                        Profile.DateEndProbation, Profile.DateQuit, AnnualLeaveMonthStart, AnnualLeaveInitAnlValue, Position, Profile,
                        lstLeaveAnl, lstAllSetting, lstHDTJob, lstDayOff.Select(m => m.DateOff).ToList(), lstLeaveAnl, userLogin);
                    double LeaveInMonth = 0;
                    List<Att_LeaveDayInfo> lstAnlInMonth = lstLeaveAnl.Where(m => m.ProfileID == Profile.ID && m.DateStart <= EndMonth && m.DateEnd >= BeginMonth).ToList();
                    foreach (var item in lstAnlInMonth)
                    {
                        var listRosterEntity = lstRoster_byProfile.Select(d => new Att_RosterEntity
                        {
                            ID = d.ID,
                            ProfileID = d.ProfileID,
                            RosterGroupName = d.RosterGroupName,
                            Type = d.Type,
                            Status = d.Status,
                            DateEnd = d.DateEnd,
                            DateStart = d.DateStart,
                            MonShiftID = d.MonShiftID,
                            TueShiftID = d.TueShiftID,
                            WedShiftID = d.WedShiftID,
                            ThuShiftID = d.ThuShiftID,
                            FriShiftID = d.FriShiftID,
                            SatShiftID = d.SatShiftID,
                            SunShiftID = d.SunShiftID,
                            MonShift2ID = d.MonShiftID,
                            TueShift2ID = d.TueShift2ID,
                            WedShift2ID = d.WedShift2ID,
                            ThuShift2ID = d.ThuShift2ID,
                            FriShift2ID = d.FriShift2ID,
                            SatShift2ID = d.SatShift2ID,
                            SunShift2ID = d.SunShift2ID
                        }).ToList();

                        var listRosterGroupEntity = lstRosterGroup.Select(d => new Att_RosterGroupEntity
                        {
                            ID = d.ID,
                            DateEnd = d.DateEnd,
                            DateStart = d.DateStart,
                            MonShiftID = d.MonShiftID,
                            TueShiftID = d.TueShiftID,
                            WedShiftID = d.WedShiftID,
                            ThuShiftID = d.ThuShiftID,
                            FriShiftID = d.FriShiftID,
                            SatShiftID = d.SatShiftID,
                            SunShiftID = d.SunShiftID,
                            RosterGroupName = d.RosterGroupName
                        }).ToList();

                        if (item.DateStart >= BeginMonth && item.DateEnd <= EndMonth)
                        {
                            //Chi cần lấy TotalDuration hoặc lấy giờ rồi lấy ca
                            if (item.DurationType == LeaveDayDurationType.E_FULLSHIFT.ToString())
                            {
                                LeaveInMonth += item.LeaveDays ?? 0;
                            }
                            else
                            {
                                //Lấy ra ca làm việc 
                                DateTime DateBeginLeave = item.DateStart.Date;
                                DateTime DateEndLeave = item.DateEnd.Date;

                                Dictionary<DateTime, Cat_Shift> dicShift = Att_AttendanceLib.GetDailyShifts(Profile != null ? Profile.ID : Guid.Empty, DateBeginLeave, DateEndLeave, listRosterEntity, listRosterGroupEntity, shifts);

                                if (dicShift != null && dicShift.ContainsKey(DateBeginLeave))
                                {
                                    Cat_Shift shift = dicShift[DateBeginLeave];
                                    if (shift != null)
                                    {
                                        double HourWorkday = shift.udStandardWorkHours > 0 ? shift.udStandardWorkHours : 8.0;

                                        LeaveInMonth += item.LeaveHours.Value / HourWorkday;
                                    }
                                }
                            }
                        }
                        else
                        {
                            DateTime DateBegin = BeginMonth > item.DateStart ? BeginMonth : item.DateStart;
                            DateTime DateEnd = EndMonth < item.DateEnd ? BeginMonth : item.DateEnd;
                            Dictionary<DateTime, Cat_Shift> dicShift = Att_AttendanceLib.GetDailyShifts(Profile != null ? Profile.ID : Guid.Empty, DateBegin, DateEnd, listRosterEntity, listRosterGroupEntity, shifts);
                            for (DateTime dateCheck = DateBegin; dateCheck <= DateEnd; dateCheck = dateCheck.AddDays(1))
                            {
                                if (Att_WorkDayHelper.IsWorkDay(dateCheck, GradeCfg, dicShift, lstDayOff) && !lstDayOff.Any(m => m.DateOff == dateCheck))
                                {
                                    LeaveInMonth++;
                                }
                            }
                        }
                    }
                    Att_AnnualDetail AnnualDetail = lstAnnualDetailInDB.Where(m => m.ProfileID == Profile.ID && m.MonthYear == Month).FirstOrDefault();
                    bool isNew = false;
                    if (AnnualDetail == null)
                    {
                        isNew = true;
                        AnnualDetail = new Att_AnnualDetail();
                    }
                    else
                    {
                        AnalyzeAnnualDetailPerProfile_Update.Add(AnnualDetail);
                    }


                    if (Profile.DateQuit != null)
                    {
                        DateTime MonthQuit = Profile.DateQuit.Value.Day >= 15 ? Profile.DateQuit.Value.AddMonths(1) : Profile.DateQuit.Value;
                        MonthQuit = new DateTime(MonthQuit.Year, MonthQuit.Month, 1);
                        if (Month >= MonthQuit)
                        {
                            AnnualDetail.IsDelete = true;
                        }
                    }
                    AnnualDetail.Available = Availale;
                    AnnualDetail.InitAvailable = AnnualLeave == null ? 0 : AnnualLeave.InitAnlValue;
                    AnnualDetail.ProfileID = Profile.ID;
                    //AnnualDetail.Hre_Profile = Profile.CopyData<Hre_Profile>();
                    AnnualDetail.Year = BeginYear.Year;
                    AnnualDetail.MonthYear = Month;
                    AnnualDetail.MonthBeginInYear = MonthStartAnl; //todo: Phần tử này để trong cấu hình chung
                    if (AnnualLeave != null && AnnualLeave.MonthResetAnlOfBeforeYear != null)
                    {
                        AnnualDetail.MonthResetInitAvailable = AnnualLeave.MonthResetAnlOfBeforeYear.Value;//todo: MonthReset Này để trong chế độ lương
                    }
                    else
                    {
                        AnnualDetail.MonthResetInitAvailable = 12;//todo: MonthReset Này để trong chế độ lương
                    }
                    AnnualDetail.MonthStartProfile = AnnualLeave == null ? 1 : AnnualLeave.MonthStart;
                    if (AnnualDetail.MonthResetInitAvailable != null && AnnualDetail.MonthResetInitAvailable != 12 && AnnualDetail.Year != null)
                    {
                        DateTime MonthReset = new DateTime(AnnualDetail.Year.Value, AnnualDetail.MonthResetInitAvailable.Value, 1);
                        AnnualDetail.IsHaveResetInitAvailable = true;
                        if (Month <= MonthReset) //Trong những tháng có
                        {
                            double delta = leaveBeginYearToMonth_Init + LeaveInMonth - AnnualDetail.InitAvailable.Value;
                            if (delta > 0)
                            {
                                AnnualDetail.TotalLeaveBefFromInitAvailable = leaveBeginYearToMonth_Init;
                                AnnualDetail.LeaveInMonthFromInitAvailable = LeaveInMonth - delta;
                                AnnualDetail.LeaveInMonth = delta;
                                AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth;
                                leaveBeginYearToMonth += delta;
                                leaveBeginYearToMonth_Init += LeaveInMonth - delta;
                            }
                            else
                            {
                                AnnualDetail.TotalLeaveBefFromInitAvailable = leaveBeginYearToMonth_Init;
                                AnnualDetail.LeaveInMonthFromInitAvailable = LeaveInMonth;
                                AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth;
                                AnnualDetail.LeaveInMonth = 0;
                                leaveBeginYearToMonth_Init += LeaveInMonth;
                            }
                        }
                        else //sau những tháng kho có
                        {
                            AnnualDetail.InitAvailable = 0;
                            AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth;
                            AnnualDetail.LeaveInMonth = LeaveInMonth;
                            leaveBeginYearToMonth += LeaveInMonth;
                        }
                    }
                    else //Bình thường
                    {
                        AnnualDetail.IsHaveResetInitAvailable = false;
                        AnnualDetail.TotalLeaveBef = leaveBeginYearToMonth;
                        AnnualDetail.LeaveInMonth = LeaveInMonth;
                        leaveBeginYearToMonth += LeaveInMonth;
                    }
                    double remain = (AnnualDetail.Available ?? 0) + (AnnualDetail.InitAvailable ?? 0) - (AnnualDetail.TotalLeaveBefFromInitAvailable ?? 0) - (AnnualDetail.LeaveInMonthFromInitAvailable ?? 0) - (AnnualDetail.TotalLeaveBef ?? 0) - (AnnualDetail.LeaveInMonth ?? 0);
                    AnnualDetail.Remain = remain;
                    AnnualDetail.Type = AnnualLeaveDetailType.E_ANNUAL_LEAVE.ToString();
                    if (isNew)
                    {
                        lstResult.Add(AnnualDetail);
                    }
                }
                return lstResult;
            }
        }