Beispiel #1
0
 public bool SetApproveKaiZenData(List <Guid> SelectIds)
 {
     using (var context = new VnrHrmDataContext())
     {
         try
         {
             var    unitOfWork                     = (IUnitOfWork)(new UnitOfWork(context));
             string status                         = string.Empty;
             var    repoKai_KaizenData             = new CustomBaseRepository <Kai_KaizenData>(unitOfWork);
             List <Kai_KaizenData> ListKaiZendData = repoKai_KaizenData.FindBy(m => m.IsDelete != true).ToList();
             foreach (var i in ListKaiZendData)
             {
                 if (SelectIds.Any(m => m == i.ID))
                 {
                     i.Status = EnumDropDown.Kai_KaizenDataStatus.E_APPROVED.ToString();
                 }
             }
             unitOfWork.SaveChanges();
             return(true);
         }
         catch
         {
             return(false);
         }
     }
 }
Beispiel #2
0
        public static List<Att_Grade> getAllGrade2(List<Guid> listProfileId, DateTime monthYear)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoAtt_Grade = new CustomBaseRepository<Att_Grade>(unitOfWork);

                List<Att_Grade> lst = new List<Att_Grade>();
                string[] strInclude = new string[] { "Cat_GradeAttendance" };

                lst = repoAtt_Grade.FindBy(gd => listProfileId.Contains(gd.ProfileID.Value)
                    && gd.MonthStart <= monthYear).OrderByDescending(prop => prop.MonthStart).ToList();

                List<Att_Grade> lstGrade = new List<Att_Grade>();
                foreach (Att_Grade grade in lst)
                {
                    Att_Grade grade1 = lstGrade.FirstOrDefault(prop => prop.ProfileID == grade.ProfileID);
                    if (grade1 == null)
                    {
                        lstGrade.Add(grade);
                    }
                }
                return lstGrade;
            }
        }
Beispiel #3
0
        public static Att_Grade GetGrade(Hre_Profile profile, DateTime effectMonth)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoAtt_Grade = new CustomBaseRepository<Att_Grade>(unitOfWork);
                //NOTE: can modify lai cau truy van de gioi han data lay len
                List<Att_Grade> lst = repoAtt_Grade
                    .FindBy(alw => alw.IsDelete == null
                        && alw.ProfileID == profile.ID
                        && alw.MonthStart <= effectMonth)
                    .OrderByDescending(alw => alw.MonthStart).ToList();

                if (lst != null && lst.Count > 0)
                {
                    // Lấy grade có ngày đến hạn, nếu không có ngày đến hạn xem như Ok không hết hạn, nếu có ngày đến hạn
                    DateTime temp = new DateTime(effectMonth.Year, effectMonth.Month, 1);
                    if (!lst[0].MonthEnd.HasValue || (lst[0].MonthEnd.HasValue && lst[0].MonthEnd.Value >= temp))
                    {
                        return lst[0];
                    }
                }
                return null;
            }
        }
Beispiel #4
0
        public List<FIN_ClaimEntity> GetClaimApprovedList(Guid UserLogin)
        {
            List<FIN_ClaimEntity> lstReturn = new List<FIN_ClaimEntity>();

            string appType = ApproveType.E_FIN_ClaimRequest.ToString();
            string status = string.Empty;
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoFIN_Claim = new CustomBaseRepository<FIN_Claim>(unitOfWork);
                List<Sys_ConditionApproved> lstCondition = new List<Sys_ConditionApproved>();
                List<Hre_ProfileEntity> lstProfile = new List<Hre_ProfileEntity>();
                GetProfileWithPermissionLogin(UserLogin, appType, out lstCondition, out lstProfile);

                var lstExpensesCondition = lstCondition.Select(s => s.ExpensesType).Distinct().ToList();
                var dataClaim = repoFIN_Claim
                    .FindBy(s => s.IsDelete == null && lstExpensesCondition.Contains(s.ExpensesType))
                    .ToList().Translate<FIN_ClaimEntity>();

                foreach (var condition in lstCondition)
                {
                    List<Guid> lstGuidOrg = GetOrgInCondition(condition);
                    var profileInOrg = lstProfile.Where(s => lstGuidOrg.Contains(s.OrgStructureID.Value)).Select(a => a.ID).ToList();
                    
                    var resultCondition = dataClaim.Where(s => profileInOrg.Contains(s.ProfileID.Value)).ToList();
                    lstReturn.AddRange(resultCondition);
                }
            }
            return lstReturn;
        }
Beispiel #5
0
        public static List <Att_Grade> getAllGrade2(List <Guid> listProfileId, DateTime monthYear)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork    = (IUnitOfWork)(new UnitOfWork(context));
                var repoAtt_Grade = new CustomBaseRepository <Att_Grade>(unitOfWork);

                List <Att_Grade> lst        = new List <Att_Grade>();
                string[]         strInclude = new string[] { "Cat_GradeAttendance" };

                lst = repoAtt_Grade.FindBy(gd => listProfileId.Contains(gd.ProfileID.Value) &&
                                           gd.MonthStart <= monthYear).OrderByDescending(prop => prop.MonthStart).ToList();

                List <Att_Grade> lstGrade = new List <Att_Grade>();
                foreach (Att_Grade grade in lst)
                {
                    Att_Grade grade1 = lstGrade.FirstOrDefault(prop => prop.ProfileID == grade.ProfileID);
                    if (grade1 == null)
                    {
                        lstGrade.Add(grade);
                    }
                }
                return(lstGrade);
            }
        }
Beispiel #6
0
        public static Att_Grade GetGrade(Hre_Profile profile, DateTime effectMonth)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork    = (IUnitOfWork)(new UnitOfWork(context));
                var repoAtt_Grade = new CustomBaseRepository <Att_Grade>(unitOfWork);
                //NOTE: can modify lai cau truy van de gioi han data lay len
                List <Att_Grade> lst = repoAtt_Grade
                                       .FindBy(alw => alw.IsDelete == null &&
                                               alw.ProfileID == profile.ID &&
                                               alw.MonthStart <= effectMonth)
                                       .OrderByDescending(alw => alw.MonthStart).ToList();

                if (lst != null && lst.Count > 0)
                {
                    // Lấy grade có ngày đến hạn, nếu không có ngày đến hạn xem như Ok không hết hạn, nếu có ngày đến hạn
                    DateTime temp = new DateTime(effectMonth.Year, effectMonth.Month, 1);
                    if (!lst[0].MonthEnd.HasValue || (lst[0].MonthEnd.HasValue && lst[0].MonthEnd.Value >= temp))
                    {
                        return(lst[0]);
                    }
                }
                return(null);
            }
        }
        /// <summary>
        /// [Hieu.Van]
        /// Xử lý Gửi yêu cầu phê duyệt
        /// </summary>
        /// <param name="LoginID"></param>
        /// <param name="userApprovedID"></param>
        /// <param name="recordID"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public string ProcessSendRequest(string host, Guid LoginID, Guid userApprovedID, Guid recordID, string type)
        {
            DataErrorCode status = DataErrorCode.Success;

            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoFIN_PurchaseRequest = new CustomBaseRepository <FIN_PurchaseRequest>(unitOfWork);
                var repoSys_UserApprove     = new CustomBaseRepository <Sys_UserApprove>(unitOfWork);

                var record = repoFIN_PurchaseRequest.FindBy(s => s.ID == recordID).FirstOrDefault();
                if (record.UserCreateID != LoginID)
                {
                    return(DataErrorCode.NoPermission.ToString());
                }
                if (record.Status == EnumDropDown.Status.E_REJECTED.ToString())
                {
                    return(DataErrorCode.Error_Reject.ToString());
                }
                if (record.Status != null)
                {
                    return(DataErrorCode.Error_SendRequest.ToString());
                }
                var userApproved = repoSys_UserApprove.FindBy(s => s.ID == userApprovedID).FirstOrDefault();
                // Lấy status hiện tại của bản ghi
                string currentStatus = record.Status;

                // truyền từ Dropdownlist chọn người duyệt, lấy ra giá trị Status tiếp theo
                string nextStatus = userApproved.CurrentStatus;

                record.Status        = nextStatus;
                record.UserApproveID = userApprovedID;
                repoFIN_PurchaseRequest.Edit(record);
                status = repoFIN_PurchaseRequest.SaveChanges();


                if (status == DataErrorCode.Success)
                {
                    if (nextStatus != "Approved")
                    {
                        status = SendMail_ToNextApproved(host, recordID, userApprovedID, nextStatus, type);
                    }

                    var repoSys_ConfigProcessApprove = new CustomBaseRepository <Sys_ConfigProcessApprove>(unitOfWork);
                    var configProcess = repoSys_ConfigProcessApprove.FindBy(s => s.IsDelete == null && s.Function == type && s.CurrentStatus == record.Status).FirstOrDefault();
                    if (configProcess == null)
                    {
                        return(DataErrorCode.Success.ToString());
                    }
                    else
                    {
                        return(DataErrorCode.Success_Forward.ToString());
                    }
                }

                return(status.ToString());
            }
        }
        /// <summary>
        /// [Hieu.Van]
        /// Xử lý Gửi yêu cầu phê duyệt
        /// </summary>
        /// <param name="LoginID"></param>
        /// <param name="userApprovedID"></param>
        /// <param name="recordID"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public string ProcessSendRequest(string host, Guid LoginID, Guid userApprovedID, Guid recordID, string type)
        {
            DataErrorCode status = DataErrorCode.Success;
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoFIN_PurchaseRequest = new CustomBaseRepository<FIN_PurchaseRequest>(unitOfWork);
                var repoSys_UserApprove = new CustomBaseRepository<Sys_UserApprove>(unitOfWork);

                var record = repoFIN_PurchaseRequest.FindBy(s => s.ID == recordID).FirstOrDefault();
                if (record.UserCreateID != LoginID)
                {
                    return DataErrorCode.NoPermission.ToString();
                }
                if (record.Status == EnumDropDown.Status.E_REJECTED.ToString())
                {
                    return DataErrorCode.Error_Reject.ToString();
                }
                if (record.Status != null)
                {
                    return DataErrorCode.Error_SendRequest.ToString();
                }
                var userApproved = repoSys_UserApprove.FindBy(s => s.ID == userApprovedID).FirstOrDefault();
                // Lấy status hiện tại của bản ghi
                string currentStatus = record.Status;

                // truyền từ Dropdownlist chọn người duyệt, lấy ra giá trị Status tiếp theo
                string nextStatus = userApproved.CurrentStatus;

                record.Status = nextStatus;
                record.UserApproveID = userApprovedID;
                repoFIN_PurchaseRequest.Edit(record);
                status = repoFIN_PurchaseRequest.SaveChanges();

                
                if (status == DataErrorCode.Success)
                {
                    if (nextStatus != "Approved")
                    {
                        status = SendMail_ToNextApproved(host, recordID, userApprovedID, nextStatus, type);
                    }

                    var repoSys_ConfigProcessApprove = new CustomBaseRepository<Sys_ConfigProcessApprove>(unitOfWork);
                    var configProcess = repoSys_ConfigProcessApprove.FindBy(s => s.IsDelete == null && s.Function == type && s.CurrentStatus == record.Status).FirstOrDefault();
                    if (configProcess == null)
                    {
                        return DataErrorCode.Success.ToString();
                    }
                    else
                    {
                        return DataErrorCode.Success_Forward.ToString();
                    }
                }

                return status.ToString();
            }
        }
        public void ComputeCommission(List <Hre_ProfileEntity> listProfile, Att_CutOffDurationEntity CutOffDuration, Guid asynTaskID, string HeaderTemplateLog, string methodPayroll, Guid CutOffDuration2ID, string UserLogin)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork       = (IUnitOfWork) new UnitOfWork(context);
                var repoSys_AsynTask = new CustomBaseRepository <Sys_AsynTask>(unitOfWork);
                var repoPayrollTable = new CustomBaseRepository <Sal_PayrollTable>(unitOfWork);
                var Sys_Model        = repoSys_AsynTask.FindBy(m => m.ID == asynTaskID).FirstOrDefault();

                if (!DeletePayrollTable(listProfile.Select(d => d.ID).ToList(), CutOffDuration.ID))
                {
                    Sys_Model.Status          = AsynTaskStatus.Error.ToString();
                    Sys_Model.Description     = "Không thể xóa bảng lương cũ";
                    Sys_Model.PercentComplete = 1;
                    unitOfWork.SaveChanges();
                }
                else
                {
                    #region Get All Data

                    DateTime DatetimeStart            = DateTime.Now;
                    ComputePayrollDataModel TotalData = PayrollServices.GetDataForComputeSalary(CutOffDuration, UserLogin);
                    //FileLog.WriteLog("", "Get Data", Common.ComputeTime(DatetimeStart, DateTime.Now));

                    #endregion

                    //Kiểm tra xem có lỗi store hay không
                    if (TotalData.Status != null && TotalData.Status != string.Empty)
                    {
                        Sys_Model.Status          = AsynTaskStatus.Error.ToString();
                        Sys_Model.Description     = TotalData.Status;
                        Sys_Model.PercentComplete = 1;
                        unitOfWork.SaveChanges();
                    }
                    else
                    {
                        #region Ghi Log
                        //Lấy đường dẫn thư mục ghi log
                        //set lại thư mục ghi log
                        //WriteLog.SettingPath = Common.GetPath("Log");
                        //WriteLog.DynamicDirectory = "ComputePayroll" + DateTime.Now.ToString("dd-MM-yyyy_HH-mm-ss");
                        //WriteLog.FileName = "LogFile";
                        //WriteLog.WriteLog(HeaderTemplateLog, "", "");
                        #endregion

                        int pageSize     = 100;               //mỗi lần tính cho 100 nhân viên
                        int totalProfile = listProfile.Count; //Tổng số nhâ viên

                        foreach (var listProfileBySize in listProfile.Chunk(pageSize))
                        {
                            ComputeCommission_Progress(TotalData, listProfileBySize.ToList(), CutOffDuration, Sys_Model.ID, totalProfile, methodPayroll, CutOffDuration2ID);
                        }
                    }
                }
            }
        }
Beispiel #10
0
 public List<Att_WorkdayEntity> GetWorkDaysByDate(DateTime DateFrom, DateTime DateTo)
 {
     using (var context = new VnrHrmDataContext())
     {
         var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
         var repo = new Att_WorkDayRepository(unitOfWork);
         var repoAtt_Workday = new CustomBaseRepository<Att_Workday>(unitOfWork);
         return repoAtt_Workday.FindBy(m => m.IsDelete == null && m.WorkDate >= DateFrom && m.WorkDate <= DateTo).Select(s => new Att_WorkdayEntity { ID = s.ID, ProfileID = s.ProfileID, InTimeRoot = s.InTimeRoot, OutTimeRoot = s.OutTimeRoot, LateEarlyDuration = s.LateEarlyDuration, ShiftID = s.ShiftID, MissInOutReason = s.MissInOutReason }).ToList<Att_WorkdayEntity>();
     }
 }
        public void CreateFormulaTemplate(List<Cat_FormulaTemplateEntity> listFormulaTemplate,Guid GradeID)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                var repoCat_FormulaTemplate = new CustomBaseRepository<Cat_FormulaTemplate>(unitOfWork);
                var repoCat_Element = new CustomBaseRepository<Cat_Element>(unitOfWork);

                #region Xử lý bảng template
                //lấy các phần tử template trong grade
                List<Cat_FormulaTemplate> listFormulaTemplateByGrade = repoCat_FormulaTemplate.FindBy(m => m.IsDelete != true && m.GradeID != null && m.GradeID == GradeID).ToList();
                //xóa các phần tử đó
                repoCat_FormulaTemplate.Delete(listFormulaTemplateByGrade);

                //insert lại các phần tử mới
                List<Cat_FormulaTemplate> listFormulaTemplateModel = listFormulaTemplate.Translate<Cat_FormulaTemplate>();
                listFormulaTemplateModel.ForEach(m => m.GradeID = GradeID);
                repoCat_FormulaTemplate.Add(listFormulaTemplateModel); 
                #endregion

                #region Xử lý bảng cat_element
                //lấy các phần tử có cùng mã code với template
                List<Cat_Element> listElement = repoCat_Element.FindBy(m => m.IsDelete != true && m.GradePayrollID == GradeID).ToList();
                listElement = listElement.Where(m => listFormulaTemplate.Any(t => t.ElementCode.ReplaceSpace() == m.ElementCode.ReplaceSpace())).ToList();
                //xóa các phần tử đó đi
                repoCat_Element.Delete(listElement);

                //tạo ra các element
                List<Cat_Element> listElementModel = new List<Cat_Element>();
                Cat_Element item = new Cat_Element();
                foreach (var template in listFormulaTemplate)
                {
                    item = new Cat_Element();
                    item.GradePayrollID = GradeID;
                    item.ElementCode = template.ElementCode.ReplaceSpace();
                    item.ElementName = template.ElementName;
                    item.Formula = template.Formula;
                    item.IsBold = template.IsBold;
                    item.Invisible = template.Invisible;
                    item.Description = template.Description;
                    item.TabType = CatElementType.Payroll.ToString();
                    item.MethodPayroll = MethodPayroll.E_NORMAL.ToString();
                    item.ElementType = CatElementType.Payroll.ToString();    
                    item.Type = EnumDropDown.ElementDataType.Double.ToString();
                    listElementModel.Add(item);
                }
                repoCat_Element.Add(listElementModel);

                unitOfWork.SaveChanges();
                #endregion

            }
        }
Beispiel #12
0
        public void AddDataForBasicSalary(string ProfileIDs, string BasicSalary, DateTime DateHire, Guid SalaryRankID,string UserLogin)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                string status = string.Empty;
                var repoBasicSalary = new CustomBaseRepository<Sal_BasicSalary>(unitOfWork);
                List<Guid> lstProfileIDs = ProfileIDs.Split(',').Select(x => Guid.Parse(x)).ToList();
                List<Sal_BasicSalary> lstBasicSalary = new List<Sal_BasicSalary>();
                //chua co cach giai quyet nen hard code lay mac dinh la VND
                var repoCurrency = new CustomBaseRepository<Cat_Currency>(unitOfWork);
                var currency = repoCurrency.FindBy(s => s.IsDelete == null && s.CurrencyName == "VND").FirstOrDefault();
                //var repoSalaryRank = new CustomBaseRepository<Cat_SalaryRank>(unitOfWork);
                //var repoSalaryClass = new CustomBaseRepository<Cat_SalaryClass>(unitOfWork);
                //var salaryRank = repoSalaryRank.FindBy(s => s.IsDelete == null && s.ID == SalaryRankID).FirstOrDefault();
                //var salaryClass = repoSalaryClass.FindBy(s => s.IsDelete == null && s.ID == salaryRank.SalaryClassID).FirstOrDefault();
                var salaryRankServices = new Cat_SalaryRankServices();
                var lstObjRank = new List<object>();
                lstObjRank.Add(null);
                lstObjRank.Add(null);
                lstObjRank.Add(1);
                lstObjRank.Add(int.MaxValue -1);
                var lstRank = salaryRankServices.GetData<Cat_SalaryRankEntity>(lstObjRank, ConstantSql.hrm_cat_sp_get_SalaryRank, UserLogin, ref status).ToList().Translate<Cat_SalaryRank>();
                var rankEntity = lstRank.Where(s => s.ID == SalaryRankID).FirstOrDefault();

                var salaryClassServices = new Cat_SalaryClassServices();
                var lstObjClass = new List<object>();
                lstObjClass.Add(null);
                lstObjClass.Add(1);
                lstObjClass.Add(int.MaxValue -1);
                var salaryClass = salaryClassServices.GetData<Cat_SalaryClassEntity>(lstObjClass, ConstantSql.hrm_cat_sp_get_SalaryClass, UserLogin, ref status).ToList().Translate<Cat_SalaryClass>();
                
                var salaryClassEntity = salaryClass.Where(s => rankEntity.SalaryClassID == s.ID).FirstOrDefault();
               
                foreach (var item in lstProfileIDs)
                {
                    Sal_BasicSalary objBasicSalary = new Sal_BasicSalary();
                    objBasicSalary.ProfileID = item;
                    objBasicSalary.GrossAmount = BasicSalary;
                    objBasicSalary.Amount = BasicSalary.Encrypt(); 
                    objBasicSalary.DateOfEffect = DateHire;
                    objBasicSalary.RankRateID = SalaryRankID;
                    objBasicSalary.CurrencyID = currency.ID;
                    objBasicSalary.ClassRateID = salaryClassEntity == null ? Guid.Empty : salaryClassEntity.ID;
                    lstBasicSalary.Add(objBasicSalary);
                }

                repoBasicSalary.Add(lstBasicSalary);
                repoBasicSalary.SaveChanges();


            }
        }
        public List <Sal_PayrollEstimateDetailEntity> GetTemplatePayrollEstimate(Sal_PayrollEstimateEntity model)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork                = (IUnitOfWork) new UnitOfWork(context);
                var repoOrgStructure          = new CustomBaseRepository <Cat_OrgStructure>(unitOfWork);
                var repoPayrollEstimateDetail = new CustomBaseRepository <Sal_PayrollEstimateDetail>(unitOfWork);

                List <Cat_OrgStructure> listOrg = repoOrgStructure.FindBy(m => m.IsDelete != true).ToList();
                if (model.OrgStructureIDs != null)
                {
                    string[] listOrdernumber = model.OrgStructureIDs.Split(',');
                    listOrg = listOrg.Where(m => listOrdernumber.Contains(m.OrderNumber.ToString())).ToList();
                }

                List <Sal_PayrollEstimateDetail> ListPayrollEstimateDetail = new List <Sal_PayrollEstimateDetail>();
                ListPayrollEstimateDetail = repoPayrollEstimateDetail.FindBy(m => m.IsDelete != true && m.PayrollEstimateID == null).ToList();

                List <Sal_PayrollEstimateDetailEntity> Result = new List <Sal_PayrollEstimateDetailEntity>();
                foreach (var i in listOrg)
                {
                    Sal_PayrollEstimateDetailEntity item = new Sal_PayrollEstimateDetailEntity();
                    item.ID = Guid.NewGuid();
                    item.OrgStructureName = i.OrgStructureName;
                    item.OrgStructureCode = i.Code;
                    item.OrgStructureID   = i.ID;
                    var _tmp = ListPayrollEstimateDetail.FirstOrDefault(m => m.OrgStructureID == i.ID);
                    if (_tmp != null)
                    {
                        item.LeaveUnpaid          = _tmp.LeaveUnpaid != null ? _tmp.LeaveUnpaid : 0;
                        item.OvertimeHoliday      = _tmp.OvertimeHoliday != null ? _tmp.OvertimeHoliday : 0;
                        item.OvertimeNightHoliday = _tmp.OvertimeNightHoliday != null ? _tmp.OvertimeNightHoliday : 0;
                        item.OvertimeNightNormal  = _tmp.OvertimeNightNormal != null ? _tmp.OvertimeNightNormal : 0;
                        item.OvertimeNightWeekend = _tmp.OvertimeNightWeekend != null ? _tmp.OvertimeNightWeekend : 0;
                        item.OvertimeNormal       = _tmp.OvertimeNormal != null ? _tmp.OvertimeNormal : 0;
                        item.OvertimeWeekend      = _tmp.OvertimeWeekend != null ? _tmp.OvertimeWeekend : 0;
                    }
                    else
                    {
                        item.LeaveUnpaid          = 0;
                        item.OvertimeHoliday      = 0;
                        item.OvertimeNightHoliday = 0;
                        item.OvertimeNightNormal  = 0;
                        item.OvertimeNightWeekend = 0;
                        item.OvertimeNormal       = 0;
                        item.OvertimeWeekend      = 0;
                    }
                    Result.Add(item);
                }
                return(Result);
            }
        }
Beispiel #14
0
        public void CreateFormulaTemplate(List <Cat_FormulaTemplateEntity> listFormulaTemplate, Guid GradeID)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork) new UnitOfWork(context);
                var repoCat_FormulaTemplate = new CustomBaseRepository <Cat_FormulaTemplate>(unitOfWork);
                var repoCat_Element         = new CustomBaseRepository <Cat_Element>(unitOfWork);

                #region Xử lý bảng template
                //lấy các phần tử template trong grade
                List <Cat_FormulaTemplate> listFormulaTemplateByGrade = repoCat_FormulaTemplate.FindBy(m => m.IsDelete != true && m.GradeID != null && m.GradeID == GradeID).ToList();
                //xóa các phần tử đó
                repoCat_FormulaTemplate.Delete(listFormulaTemplateByGrade);

                //insert lại các phần tử mới
                List <Cat_FormulaTemplate> listFormulaTemplateModel = listFormulaTemplate.Translate <Cat_FormulaTemplate>();
                listFormulaTemplateModel.ForEach(m => m.GradeID = GradeID);
                repoCat_FormulaTemplate.Add(listFormulaTemplateModel);
                #endregion

                #region Xử lý bảng cat_element
                //lấy các phần tử có cùng mã code với template
                List <Cat_Element> listElement = repoCat_Element.FindBy(m => m.IsDelete != true && m.GradePayrollID == GradeID).ToList();
                listElement = listElement.Where(m => listFormulaTemplate.Any(t => t.ElementCode.ReplaceSpace() == m.ElementCode.ReplaceSpace())).ToList();
                //xóa các phần tử đó đi
                repoCat_Element.Delete(listElement);

                //tạo ra các element
                List <Cat_Element> listElementModel = new List <Cat_Element>();
                Cat_Element        item             = new Cat_Element();
                foreach (var template in listFormulaTemplate)
                {
                    item = new Cat_Element();
                    item.GradePayrollID = GradeID;
                    item.ElementCode    = template.ElementCode.ReplaceSpace();
                    item.ElementName    = template.ElementName;
                    item.Formula        = template.Formula;
                    item.IsBold         = template.IsBold;
                    item.Invisible      = template.Invisible;
                    item.Description    = template.Description;
                    item.TabType        = CatElementType.Payroll.ToString();
                    item.MethodPayroll  = MethodPayroll.E_NORMAL.ToString();
                    item.ElementType    = CatElementType.Payroll.ToString();
                    item.Type           = EnumDropDown.ElementDataType.Double.ToString();
                    listElementModel.Add(item);
                }
                repoCat_Element.Add(listElementModel);

                unitOfWork.SaveChanges();
                #endregion
            }
        }
Beispiel #15
0
        public void AddDataForBasicSalary(string ProfileIDs, string BasicSalary, DateTime DateHire, Guid SalaryRankID, string UserLogin)
        {
            using (var context = new VnrHrmDataContext())
            {
                var                    unitOfWork      = (IUnitOfWork)(new UnitOfWork(context));
                string                 status          = string.Empty;
                var                    repoBasicSalary = new CustomBaseRepository <Sal_BasicSalary>(unitOfWork);
                List <Guid>            lstProfileIDs   = ProfileIDs.Split(',').Select(x => Guid.Parse(x)).ToList();
                List <Sal_BasicSalary> lstBasicSalary  = new List <Sal_BasicSalary>();
                //chua co cach giai quyet nen hard code lay mac dinh la VND
                var repoCurrency = new CustomBaseRepository <Cat_Currency>(unitOfWork);
                var currency     = repoCurrency.FindBy(s => s.IsDelete == null && s.CurrencyName == "VND").FirstOrDefault();
                //var repoSalaryRank = new CustomBaseRepository<Cat_SalaryRank>(unitOfWork);
                //var repoSalaryClass = new CustomBaseRepository<Cat_SalaryClass>(unitOfWork);
                //var salaryRank = repoSalaryRank.FindBy(s => s.IsDelete == null && s.ID == SalaryRankID).FirstOrDefault();
                //var salaryClass = repoSalaryClass.FindBy(s => s.IsDelete == null && s.ID == salaryRank.SalaryClassID).FirstOrDefault();
                var salaryRankServices = new Cat_SalaryRankServices();
                var lstObjRank         = new List <object>();
                lstObjRank.Add(null);
                lstObjRank.Add(null);
                lstObjRank.Add(1);
                lstObjRank.Add(int.MaxValue - 1);
                var lstRank    = salaryRankServices.GetData <Cat_SalaryRankEntity>(lstObjRank, ConstantSql.hrm_cat_sp_get_SalaryRank, UserLogin, ref status).ToList().Translate <Cat_SalaryRank>();
                var rankEntity = lstRank.Where(s => s.ID == SalaryRankID).FirstOrDefault();

                var salaryClassServices = new Cat_SalaryClassServices();
                var lstObjClass         = new List <object>();
                lstObjClass.Add(null);
                lstObjClass.Add(1);
                lstObjClass.Add(int.MaxValue - 1);
                var salaryClass = salaryClassServices.GetData <Cat_SalaryClassEntity>(lstObjClass, ConstantSql.hrm_cat_sp_get_SalaryClass, UserLogin, ref status).ToList().Translate <Cat_SalaryClass>();

                var salaryClassEntity = salaryClass.Where(s => rankEntity.SalaryClassID == s.ID).FirstOrDefault();

                foreach (var item in lstProfileIDs)
                {
                    Sal_BasicSalary objBasicSalary = new Sal_BasicSalary();
                    objBasicSalary.ProfileID    = item;
                    objBasicSalary.GrossAmount  = BasicSalary;
                    objBasicSalary.Amount       = BasicSalary.Encrypt();
                    objBasicSalary.DateOfEffect = DateHire;
                    objBasicSalary.RankRateID   = SalaryRankID;
                    objBasicSalary.CurrencyID   = currency.ID;
                    objBasicSalary.ClassRateID  = salaryClassEntity == null ? Guid.Empty : salaryClassEntity.ID;
                    lstBasicSalary.Add(objBasicSalary);
                }

                repoBasicSalary.Add(lstBasicSalary);
                repoBasicSalary.SaveChanges();
            }
        }
Beispiel #16
0
 public ResultsObject UpdateStatus(string Ids,string Status)
 {
     using (var context = new VnrHrmDataContext())
     {
         var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
         var repoHDTJobGroup = new CustomBaseRepository<Cat_HDTJobGroup>(unitOfWork);
         List<Cat_HDTJobGroup> listHDTJob = repoHDTJobGroup.FindBy(m => m.IsDelete != true).ToList();
         string[] ListIds = Ids.Split(',');
         listHDTJob = listHDTJob.Where(m => ListIds.Contains(m.ID.ToString())).ToList();
         listHDTJob.ForEach(m => m.Status = Status);
         unitOfWork.SaveChanges();
         return new ResultsObject();
     }
 }
Beispiel #17
0
 public ResultsObject UpdateStatus(string Ids, string Status)
 {
     using (var context = new VnrHrmDataContext())
     {
         var unitOfWork      = (IUnitOfWork) new UnitOfWork(context);
         var repoHDTJobGroup = new CustomBaseRepository <Cat_HDTJobGroup>(unitOfWork);
         List <Cat_HDTJobGroup> listHDTJob = repoHDTJobGroup.FindBy(m => m.IsDelete != true).ToList();
         string[] ListIds = Ids.Split(',');
         listHDTJob = listHDTJob.Where(m => ListIds.Contains(m.ID.ToString())).ToList();
         listHDTJob.ForEach(m => m.Status = Status);
         unitOfWork.SaveChanges();
         return(new ResultsObject());
     }
 }
        public ResultsObject UpdateSatus(List <Guid> listIds, string status)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork           = (IUnitOfWork) new UnitOfWork(context);
                var repoUnusualAllowance = new CustomBaseRepository <Sal_UnusualAllowance>(unitOfWork);

                List <Sal_UnusualAllowance> listResult = repoUnusualAllowance.FindBy(m => m.IsDelete != true).ToList();
                listResult = listResult.Where(m => listIds.Contains(m.ID)).ToList();
                listResult.ForEach(m => m.Status = status);
                unitOfWork.SaveChanges();
                return(new ResultsObject());
            }
        }
Beispiel #19
0
        public ResultsObject SaveChangeHoldSalary(List <Sal_HoldSalaryEntity> ListEntity)
        {
            try
            {
                using (var context = new VnrHrmDataContext())
                {
                    var unitOfWork         = (IUnitOfWork) new UnitOfWork(context);
                    var repoSal_HoldSalary = new CustomBaseRepository <Sal_HoldSalary>(unitOfWork);
                    List <Sal_HoldSalary> TotalHoldSalary = repoSal_HoldSalary.FindBy(m => m.IsDelete != true).ToList();

                    foreach (var i in ListEntity)
                    {
                        #region Kiểm tra nhân viên đã có dữ liệu giữ lương hay chưa

                        Sal_HoldSalary HoldSalaryByProfile = TotalHoldSalary.FirstOrDefault(m => m.ProfileID == i.ProfileID && m.MonthSalary != null && m.MonthSalary.Value.Day == i.MonthSalary.Value.Day && m.TimeAnalyzeID != null && m.TimeAnalyzeID == i.TimeAnalyzeID);
                        if (HoldSalaryByProfile != null)
                        {
                            if (HoldSalaryByProfile.Status == EnumDropDown.HoldSalaryStatus.E_APPROVED.ToString())
                            {
                                continue;
                            }
                            else
                            {
                                HoldSalaryByProfile.AmountSalary      = i.AmountSalary;
                                HoldSalaryByProfile.IsLeaveContinuous = i.IsLeaveContinuous;
                                HoldSalaryByProfile.IsLeaveM          = i.IsLeaveM;
                                HoldSalaryByProfile.Terminate         = i.Terminate;
                                HoldSalaryByProfile.TimeAnalyzeID     = i.TimeAnalyzeID;
                            }
                        }
                        else
                        {
                            Sal_HoldSalary HoldSalary = i.Copy <Sal_HoldSalary>();
                            repoSal_HoldSalary.Add(HoldSalary);
                        }
                        #endregion
                    }
                    unitOfWork.SaveChanges();
                    return(new ResultsObject());
                }
            }
            catch (Exception ex)
            {
                return(new ResultsObject()
                {
                    Success = false, Messenger = ex.Message
                });
            }
        }
Beispiel #20
0
        public List<Sys_UserInfoEntity> ResourceUserApproved(Guid orgEmp, string type)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoSys_UserApprove = new CustomBaseRepository<Sys_UserApprove>(unitOfWork);
                var repoCat_OrgStructure = new CustomBaseRepository<Cat_OrgStructure>(unitOfWork);
                var repoSys_UserInfo = new CustomBaseRepository<Sys_UserInfo>(unitOfWork);

                List<object> listObj = new List<object>();
                listObj.Add(null);
                listObj.Add(string.Empty);
                listObj.Add(string.Empty);

                string status = string.Empty;
                //var dataProfile = GetData<Hre_Profile>(listObj, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, ref status).ToList();
                var dataUA = repoSys_UserApprove.FindBy(s => s.IsDelete == null && s.Type == type).ToList();

                // lấy UserInfo của Người Duyệt
                var lstUserInfo = dataUA.Select(s => s.UserApproveID).Distinct().ToList();
                // Lấy guid Nhân Viên từ UserInfo
                var lstUser = repoSys_UserInfo.FindBy(s => lstUserInfo.Contains(s.ID)).ToList();
                //var lstProGuid = lstUser.Select(s => s.ProfileID).Distinct().ToList();
                var dataCat_OrgStructure = repoCat_OrgStructure.FindBy(s => s.OrderNumber != null).ToList();

                List<Sys_UserInfoEntity> lstReturn = new List<Sys_UserInfoEntity>();
                foreach (var item in dataUA)
                {
                    var user = lstUser.Where(d => d.ID == item.UserApproveID).FirstOrDefault();
                    //var idUser = lstUserInfo.Where(s => s == item.UserApproveID).FirstOrDefault();
                    //var idOrg = lstUser.Where(s => s.ID == idUser).Select(s => s.OrgStructureID).FirstOrDefault();

                    if (item.OrgStructureID != null && IsParentOrgStructure(orgEmp, item.OrgStructureID.Value, dataCat_OrgStructure))
                    {
                        Sys_UserInfoEntity entity = new Sys_UserInfoEntity()
                        {
                            ID = item.UserApproveID,
                            UserInfoName = user.UserInfoName,
                            UserLogin = user.UserLogin

                        };
                        lstReturn.Add(entity);
                    }
                }
                return lstReturn;
            }
        }
Beispiel #21
0
        public string[] SetWaitApproveKaiZenData(List <Guid> SelectIds)
        {
            using (var context = new VnrHrmDataContext())
            {
                try
                {
                    var    unitOfWork                     = (IUnitOfWork)(new UnitOfWork(context));
                    string status                         = string.Empty;
                    var    repoKai_KaizenData             = new CustomBaseRepository <Kai_KaizenData>(unitOfWork);
                    var    repoKai_RankMark               = new CustomBaseRepository <Kai_RankMark>(unitOfWork);
                    List <Kai_KaizenData> ListKaiZendData = repoKai_KaizenData.FindBy(m => m.IsDelete != true).ToList();
                    List <Kai_RankMark>   ListKaiRank     = repoKai_RankMark.FindBy(m => m.IsDelete != true).ToList();

                    int    Pass     = 0;
                    int    Fail     = 0;
                    string FailCode = string.Empty;

                    foreach (var i in ListKaiZendData)
                    {
                        if (SelectIds.Any(m => m == i.ID))
                        {
                            #region Kiểm tra hợp lệ vùng điểm
                            List <Kai_RankMark> ListKaiRankByRankMark = ListKaiRank.Where(m => m.MarkIdea == i.MarkIdea).ToList();
                            if (ListKaiRankByRankMark.Any(m => m.MarkPerform == i.MarkPerform))
                            {
                                i.Status = EnumDropDown.Kai_KaizenDataStatus.E_WATTING_APPROVED.ToString();
                                Pass++;
                            }
                            else
                            {
                                Fail++;
                                FailCode += i.Hre_Profile.CodeEmp + ",";
                            }
                            #endregion
                        }
                    }
                    unitOfWork.SaveChanges();

                    return(new string[] { Pass.ToString(), Fail.ToString(), FailCode });
                }
                catch
                {
                    return(new string[] { "0", "0", string.Empty });
                }
            }
        }
Beispiel #22
0
        public int[] ApprevedKaiZenData(List <Guid> selectedIds, DateTime MonthYear, Guid UnusualEDTypeID, Guid Currency)
        {
            using (var context = new VnrHrmDataContext())
            {
                string status                   = string.Empty;
                var    unitOfWork               = (IUnitOfWork) new UnitOfWork(context);
                var    repoKai_KaizenData       = new CustomBaseRepository <Kai_KaizenData>(unitOfWork);
                var    repoSal_UnusualAllowance = new CustomBaseRepository <Sal_UnusualAllowance>(unitOfWork);
                List <Sal_UnusualAllowance> listUnusualAllowance = new List <Sal_UnusualAllowance>();

                //lọc ra các kaizen được chọn
                List <Kai_KaizenData> listKaiZendata = repoKai_KaizenData.FindBy(m => m.IsDelete != true).ToList();
                listKaiZendata = listKaiZendata.Where(m => m.Status == EnumDropDown.Kai_KaizenDataStatus.E_APPROVED.ToString() && selectedIds.Any(t => t == m.ID)).ToList();

                int Pass = 0;
                int Fail = 0;

                Sal_UnusualAllowance item = new Sal_UnusualAllowance();
                foreach (var KaiZenItem in listKaiZendata)
                {
                    if (KaiZenItem.DateTransferPayment == null && (KaiZenItem.IsPaymentOut == null || KaiZenItem.IsPaymentOut == false))
                    {
                        item                 = new Sal_UnusualAllowance();
                        item.ProfileID       = KaiZenItem.ProfileID != null ? (Guid)KaiZenItem.ProfileID : Guid.NewGuid();
                        item.MonthStart      = new DateTime(MonthYear.Year, MonthYear.Month, 1);
                        item.MonthEnd        = new DateTime(MonthYear.Year, MonthYear.Month, 1).AddMonths(1).AddDays(-1);
                        item.Type            = EnumDropDown.EDType.E_EARNING.ToString();
                        item.UnusualEDTypeID = UnusualEDTypeID;
                        item.CurrencyID      = Currency;
                        item.Amount          = KaiZenItem.SumAmount != null ? KaiZenItem.SumAmount : 0;
                        listUnusualAllowance.Add(item);

                        KaiZenItem.DateTransferPayment = MonthYear;
                        Pass++;
                    }
                    else
                    {
                        Fail++;
                    }
                }
                repoSal_UnusualAllowance.Add(listUnusualAllowance);
                unitOfWork.SaveChanges();
                return(new int[] { Pass, Fail });
            }
        }
        public bool HasConfigAnnualLeaveAtTotalConfig()
        {
            var isConfig = false;
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoSys_AppConfig = new CustomBaseRepository<Sys_AppConfig>(unitOfWork);

                string E_STANDARD_WORKDAY = AppConfig.E_STANDARD_WORKDAY.ToString();
                var appconfig = repoSys_AppConfig.FindBy(p => p.Info == E_STANDARD_WORKDAY).FirstOrDefault();
                if (appconfig == null || string.IsNullOrEmpty(appconfig.Value78) ||
                    string.IsNullOrEmpty(appconfig.Value79))
                {
                    //xuat thong bao : Vui lòng cấu hình tham số và công thức tính phép năm ở "Cấu hình chung" (PleaseConfigAnnualLeaveAtTotalConfig)
                    return false;
                }
            }
            return isConfig;
        }
Beispiel #24
0
 public string DeleteColumMode(Guid id, string gridName)
 {
     using (var context = new VnrHrmDataContext())
     {
         var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
         try
         {
             var repo   = new CustomBaseRepository <Sys_ColumnMode>(unitOfWork);
             var entity = repo.FindBy(d => d.UserInfoID == id && d.GridControlName == gridName).FirstOrDefault();
             unitOfWork.RemoveObject(typeof(Sys_ColumnMode), entity);
             unitOfWork.SaveChanges(Guid.Empty);
             return(NotificationType.Success.ToString());
         }
         catch (Exception ex)
         {
             return(NotificationType.Error + "," + ex.Message);
         }
     }
 }
        public bool SaveTemplatePayrollEstimate(List <Sal_PayrollEstimateDetailEntity> listEntity)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork                = (IUnitOfWork) new UnitOfWork(context);
                var repoOrgStructure          = new CustomBaseRepository <Cat_OrgStructure>(unitOfWork);
                var repoPayrollEstimateDetail = new CustomBaseRepository <Sal_PayrollEstimateDetail>(unitOfWork);

                List <Sal_PayrollEstimateDetail> ListPayrollEstimateDetail = new List <Sal_PayrollEstimateDetail>();
                ListPayrollEstimateDetail = repoPayrollEstimateDetail.FindBy(m => m.IsDelete != true && m.PayrollEstimateID == null).ToList();

                foreach (var i in listEntity)
                {
                    var _tmp = ListPayrollEstimateDetail.FirstOrDefault(m => m.OrgStructureID == i.OrgStructureID);
                    if (_tmp != null)
                    {
                        _tmp.LeaveUnpaid          = i.LeaveUnpaid;
                        _tmp.OvertimeHoliday      = i.OvertimeHoliday;
                        _tmp.OvertimeNightHoliday = i.OvertimeNightHoliday;
                        _tmp.OvertimeNightNormal  = i.OvertimeNightNormal;
                        _tmp.OvertimeNightWeekend = i.OvertimeNightWeekend;
                        _tmp.OvertimeNormal       = i.OvertimeNormal;
                        _tmp.OvertimeWeekend      = i.OvertimeWeekend;
                    }
                    else
                    {
                        Sal_PayrollEstimateDetail item = new Sal_PayrollEstimateDetail();
                        item.ID                   = Guid.NewGuid();
                        item.OrgStructureID       = i.OrgStructureID;
                        item.LeaveUnpaid          = i.LeaveUnpaid;
                        item.OvertimeHoliday      = i.OvertimeHoliday;
                        item.OvertimeNightHoliday = i.OvertimeNightHoliday;
                        item.OvertimeNightNormal  = i.OvertimeNightNormal;
                        item.OvertimeNightWeekend = i.OvertimeNightWeekend;
                        item.OvertimeNormal       = i.OvertimeNormal;
                        item.OvertimeWeekend      = i.OvertimeWeekend;
                        repoPayrollEstimateDetail.Add(item);
                    }
                }
                unitOfWork.SaveChanges();
                return(true);
            }
        }
Beispiel #26
0
        public List <Sys_UserApproveEntity> GetUserApprovedForMulti_E_FIN_ClaimRequest(Guid recordID, string userLogin)
        {
            List <Sys_UserApproveEntity> lstReturn = new List <Sys_UserApproveEntity>();

            using (var context = new VnrHrmDataContext())
            {
                var    type       = ApproveType.E_FIN_ClaimRequest.ToString();
                var    unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                string status     = string.Empty;

                var    repoSys_ConfigProcessApprove = new CustomBaseRepository <Sys_ConfigProcessApprove>(unitOfWork);
                var    repoSys_UserApprove          = new CustomBaseRepository <Sys_UserApprove>(unitOfWork);
                var    repoSys_UserInfo             = new CustomBaseRepository <Sys_UserInfo>(unitOfWork);
                var    lstUserInfo   = repoSys_UserInfo.FindBy(s => s.IsDelete == null).ToList();
                var    record        = GetData <FIN_ClaimEntity>(recordID, ConstantSql.hrm_hr_sp_get_ClaimById, userLogin, ref status).FirstOrDefault();
                string currentStatus = record.Status;
                var    configProcess = repoSys_ConfigProcessApprove.FindBy(s => s.IsDelete == null && s.Function == type && s.CurrentStatus == currentStatus).FirstOrDefault();

                List <ElementFormula> listFomula = new List <ElementFormula>();
                ElementFormula        FomulaItem = new ElementFormula("Total", record.Total, 0);
                ElementFormula        statusItem = new ElementFormula(configProcess.NextStatusFormular, configProcess.NextStatusFormular, 1);
                listFomula.Add(FomulaItem);
                listFomula.Add(statusItem);
                string nextStatus = GetObjectValue(new List <Cat_ElementEntity>(), listFomula, configProcess.NextStatusFormular).ToString();

                var lstUserApprove          = repoSys_UserApprove.FindBy(s => s.IsDelete == null && s.Type == type && s.CurrentStatus == nextStatus).ToList();
                Sys_UserApproveEntity model = new Sys_UserApproveEntity();
                foreach (var item in lstUserApprove)
                {
                    if (item.UserRequestID != null && item.UserRequestID == record.UserCreateID)
                    {
                        model = new Sys_UserApproveEntity();
                        var temp = lstUserInfo.Where(s => s.ID == item.UserApproveID).FirstOrDefault();
                        model.ID = item.ID;
                        model.UserApproveName = temp.UserInfoName;
                        model.UserApproveID   = item.UserApproveID;
                        lstReturn.Add(model);
                    }
                }
            }
            return(lstReturn);
        }
Beispiel #27
0
 public bool SaveCustomAccumulate(Guid ID, double AccumulateRevice)
 {
     using (var context = new VnrHrmDataContext())
     {
         try
         {
             var            unitOfWork         = (IUnitOfWork)(new UnitOfWork(context));
             string         status             = string.Empty;
             var            repoKai_KaizenData = new CustomBaseRepository <Kai_KaizenData>(unitOfWork);
             Kai_KaizenData KaiZendData        = repoKai_KaizenData.FindBy(m => m.ID == ID).FirstOrDefault();
             KaiZendData.AccumulateRevice = AccumulateRevice;
             unitOfWork.SaveChanges();
             return(true);
         }
         catch
         {
             return(false);
         }
     }
 }
Beispiel #28
0
 public bool SaveAmountKaiZen(List <Guid> SelectIds)
 {
     using (var context = new VnrHrmDataContext())
     {
         try
         {
             var    unitOfWork         = (IUnitOfWork)(new UnitOfWork(context));
             string status             = string.Empty;
             var    repoKai_KaizenData = new CustomBaseRepository <Kai_KaizenData>(unitOfWork);
             List <Kai_KaizenData> listKai_KaizenData = repoKai_KaizenData.FindBy(m => m.IsDelete != true && SelectIds.Any(t => t == m.ID)).ToList();
             listKai_KaizenData.ForEach(m => m.AmountTransfered = m.SumAmount);
             unitOfWork.SaveChanges();
             return(true);
         }
         catch
         {
             return(false);
         }
     }
 }
Beispiel #29
0
        public bool HasConfigAnnualLeaveAtTotalConfig()
        {
            var isConfig = false;

            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork        = (IUnitOfWork)(new UnitOfWork(context));
                var repoSys_AppConfig = new CustomBaseRepository <Sys_AppConfig>(unitOfWork);

                string E_STANDARD_WORKDAY = AppConfig.E_STANDARD_WORKDAY.ToString();
                var    appconfig          = repoSys_AppConfig.FindBy(p => p.Info == E_STANDARD_WORKDAY).FirstOrDefault();
                if (appconfig == null || string.IsNullOrEmpty(appconfig.Value78) ||
                    string.IsNullOrEmpty(appconfig.Value79))
                {
                    //xuat thong bao : Vui lòng cấu hình tham số và công thức tính phép năm ở "Cấu hình chung" (PleaseConfigAnnualLeaveAtTotalConfig)
                    return(false);
                }
            }
            return(isConfig);
        }
Beispiel #30
0
        public List<Sys_UserApproveEntity> GetUserApprovedForMulti_E_FIN_ClaimRequest(Guid recordID, string userLogin)
        {
            List<Sys_UserApproveEntity> lstReturn = new List<Sys_UserApproveEntity>();
            using (var context = new VnrHrmDataContext())
            {
                var type = ApproveType.E_FIN_ClaimRequest.ToString();
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                string status = string.Empty;

                var repoSys_ConfigProcessApprove = new CustomBaseRepository<Sys_ConfigProcessApprove>(unitOfWork);
                var repoSys_UserApprove = new CustomBaseRepository<Sys_UserApprove>(unitOfWork);
                var repoSys_UserInfo = new CustomBaseRepository<Sys_UserInfo>(unitOfWork);
                var lstUserInfo = repoSys_UserInfo.FindBy(s => s.IsDelete == null).ToList();
                var record = GetData<FIN_ClaimEntity>(recordID, ConstantSql.hrm_hr_sp_get_ClaimById, userLogin, ref status).FirstOrDefault();
                string currentStatus = record.Status;
                var configProcess = repoSys_ConfigProcessApprove.FindBy(s => s.IsDelete == null && s.Function == type && s.CurrentStatus == currentStatus).FirstOrDefault();

                List<ElementFormula> listFomula = new List<ElementFormula>();
                ElementFormula FomulaItem = new ElementFormula("Total", record.Total, 0);
                ElementFormula statusItem = new ElementFormula(configProcess.NextStatusFormular, configProcess.NextStatusFormular, 1);
                listFomula.Add(FomulaItem);
                listFomula.Add(statusItem);
                string nextStatus = GetObjectValue(new List<Cat_ElementEntity>(), listFomula, configProcess.NextStatusFormular).ToString();

                var lstUserApprove = repoSys_UserApprove.FindBy(s => s.IsDelete == null && s.Type == type && s.CurrentStatus == nextStatus).ToList();
                Sys_UserApproveEntity model = new Sys_UserApproveEntity();
                foreach (var item in lstUserApprove)
                {
                    if (item.UserRequestID != null && item.UserRequestID == record.UserCreateID)
                    {
                        model = new Sys_UserApproveEntity();
                        var temp = lstUserInfo.Where(s => s.ID == item.UserApproveID).FirstOrDefault();
                        model.ID = item.ID;
                        model.UserApproveName = temp.UserInfoName;
                        model.UserApproveID = item.UserApproveID;
                        lstReturn.Add(model);
                    }
                }
            }
            return lstReturn;
        }
 public string GetNextStatusOfRecord(Guid recordID)
 {
     using (var context = new VnrHrmDataContext())
     {
         string type       = ApproveType.E_FIN_PurchaseRequest.ToString();
         var    unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
         var    repoSys_ConfigProcessApprove = new CustomBaseRepository <Sys_ConfigProcessApprove>(unitOfWork);
         var    UserLogin                 = string.Empty;
         string stt                       = string.Empty;
         var    record                    = GetData <FIN_PurchaseRequestEntity>(recordID, ConstantSql.hrm_hr_sp_get_PurchaseRequestById, UserLogin, ref stt).FirstOrDefault();
         var    configProcess             = repoSys_ConfigProcessApprove.FindBy(s => s.IsDelete == null && s.Function == type && s.CurrentStatus == record.Status).FirstOrDefault();
         double total                     = record.Total != null ? record.Total.Value : 0.0;
         List <ElementFormula> listFomula = new List <ElementFormula>();
         ElementFormula        FomulaItem = new ElementFormula("Total", total, 0);
         ElementFormula        statusItem = new ElementFormula(configProcess.NextStatusFormular, configProcess.NextStatusFormular, 1);
         listFomula.Add(FomulaItem);
         listFomula.Add(statusItem);
         string nextStatus = GetObjectValue(new List <Cat_ElementEntity>(), listFomula, configProcess.NextStatusFormular).ToString();
         return(nextStatus);
     }
 }
Beispiel #32
0
        public bool SaveAmountKaiZen(List<Guid> SelectIds)
        {
            using (var context = new VnrHrmDataContext())
            {
                try
                {
                    var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                    string status = string.Empty;
                    var repoKai_KaizenData = new CustomBaseRepository<Kai_KaizenData>(unitOfWork);
                    List<Kai_KaizenData> listKai_KaizenData = repoKai_KaizenData.FindBy(m => m.IsDelete != true && SelectIds.Any(t => t == m.ID)).ToList();
                    listKai_KaizenData.ForEach(m => m.AmountTransfered = m.SumAmount);
                    unitOfWork.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;
                }

            }
        }
Beispiel #33
0
        public string ActionApproved(string selectedIds)
        {
            using (var context = new VnrHrmDataContext())
            {
                string message = string.Empty;
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                //var repo = new Hre_WorkHistoryRepository(unitOfWork);
                var repoWorkHistory = new CustomBaseRepository<Hre_WorkHistory>(unitOfWork);
                var repoProfile = new CustomBaseRepository<Hre_Profile>(unitOfWork);
                List<Guid> lstIds = selectedIds.Split(',').Select(x => Guid.Parse(x)).ToList();
                var lstWorkHistorys = repoWorkHistory.FindBy(m => lstIds.Contains(m.ID)).ToList();
                foreach (var WorkHistory in lstWorkHistorys)
                {
                    WorkHistory.Status = WorkHistoryStatus.E_APPROVED.ToString();

                    if (WorkHistory.DateEffective != null && WorkHistory.DateEffective <= DateTime.Now.Date)
                    {
                        string status = string.Empty;
                        Hre_Profile profile = repoProfile.FindBy(m => m.IsDelete != true && m.ID == WorkHistory.ProfileID).FirstOrDefault();
                        if (profile != null)
                        {
                            profile.OrgStructureID = WorkHistory.OrganizationStructureID;
                            profile.JobTitleID = WorkHistory.JobTitleID;
                            profile.PositionID = WorkHistory.PositionID;
                            profile.DateOfEffect = WorkHistory.DateEffective;
                            profile.LaborType = WorkHistory.LaborType;
                            profile.CostCentreID = WorkHistory.CostCentreID;
                            profile.FormType = WorkHistory.FormType;
                            profile.EmpTypeID = WorkHistory.EmployeeTypeID;
                            profile.WorkingPlace = WorkHistory.WorkLocation;
                            //profileServices.Edit(profile);
                        }
                    }
                }
                unitOfWork.SaveChanges();
                message = NotificationType.Success.ToString();
                return message;
            }
        }
Beispiel #34
0
        public string GetNextStatusOfRecord(Guid recordID)
        {
            using (var context = new VnrHrmDataContext())
            {
                string type = ApproveType.E_FIN_PurchaseRequest.ToString();
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoSys_ConfigProcessApprove = new CustomBaseRepository<Sys_ConfigProcessApprove>(unitOfWork);
                var UserLogin = string.Empty;
                string stt = string.Empty;
                var record = GetData<FIN_PurchaseRequestEntity>(recordID, ConstantSql.hrm_hr_sp_get_PurchaseRequestById, UserLogin, ref stt).FirstOrDefault();
                var configProcess = repoSys_ConfigProcessApprove.FindBy(s => s.IsDelete == null && s.Function == type && s.CurrentStatus == record.Status).FirstOrDefault();
                double total = record.Total != null ? record.Total.Value : 0.0;
                List<ElementFormula> listFomula = new List<ElementFormula>();
                ElementFormula FomulaItem = new ElementFormula("Total", total, 0);
                ElementFormula statusItem = new ElementFormula(configProcess.NextStatusFormular, configProcess.NextStatusFormular, 1);
                listFomula.Add(FomulaItem);
                listFomula.Add(statusItem);
                string nextStatus = GetObjectValue(new List<Cat_ElementEntity>(), listFomula, configProcess.NextStatusFormular).ToString();
                return nextStatus;
            }

        }
Beispiel #35
0
        public string ActionApproved(string selectedIds)
        {
            using (var context = new VnrHrmDataContext())
            {
                string message    = string.Empty;
                var    unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                //var repo = new Hre_WorkHistoryRepository(unitOfWork);
                var         repoWorkHistory = new CustomBaseRepository <Hre_WorkHistory>(unitOfWork);
                var         repoProfile     = new CustomBaseRepository <Hre_Profile>(unitOfWork);
                List <Guid> lstIds          = selectedIds.Split(',').Select(x => Guid.Parse(x)).ToList();
                var         lstWorkHistorys = repoWorkHistory.FindBy(m => lstIds.Contains(m.ID)).ToList();
                foreach (var WorkHistory in lstWorkHistorys)
                {
                    WorkHistory.Status = WorkHistoryStatus.E_APPROVED.ToString();

                    if (WorkHistory.DateEffective != null && WorkHistory.DateEffective <= DateTime.Now.Date)
                    {
                        string      status  = string.Empty;
                        Hre_Profile profile = repoProfile.FindBy(m => m.IsDelete != true && m.ID == WorkHistory.ProfileID).FirstOrDefault();
                        if (profile != null)
                        {
                            profile.OrgStructureID = WorkHistory.OrganizationStructureID;
                            profile.JobTitleID     = WorkHistory.JobTitleID;
                            profile.PositionID     = WorkHistory.PositionID;
                            profile.DateOfEffect   = WorkHistory.DateEffective;
                            profile.LaborType      = WorkHistory.LaborType;
                            profile.CostCentreID   = WorkHistory.CostCentreID;
                            profile.FormType       = WorkHistory.FormType;
                            profile.EmpTypeID      = WorkHistory.EmployeeTypeID;
                            profile.WorkingPlace   = WorkHistory.WorkLocation;
                            //profileServices.Edit(profile);
                        }
                    }
                }
                unitOfWork.SaveChanges();
                message = NotificationType.Success.ToString();
                return(message);
            }
        }
Beispiel #36
0
        /// <summary>
        /// Button Tìm Kiếm Trong Phân Tích BHXH
        /// </summary>
        /// <param name="Year"></param>
        /// <param name="orgStructure"></param>
        /// <param name="LstProfileStatus"></param>
        /// <returns></returns>
        public List <Att_AnnualLeaveDetailEntity> SearchAnnualInsuranceLeaveDetail(int Year, string orgStructure, string LstProfileStatus, string UserLogin)
        {
            using (var context = new VnrHrmDataContext())
            {
                string status     = string.Empty;
                var    unitOfWork = (IUnitOfWork) new UnitOfWork(context);
                var    repoAtt_AnnualLeaveDetail = new CustomBaseRepository <Att_AnnualLeaveDetail>(unitOfWork);

                List <object> lstObj = new List <object>();
                lstObj.Add(orgStructure);
                lstObj.Add(null);
                lstObj.Add(null);
                var lstProfileQuery = GetData <Hre_ProfileEntity>(lstObj, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, UserLogin, ref status).ToList();

                string E_INSURANCE_LEAVE = AnnualLeaveDetailType.E_INSURANCE_LEAVE.ToString();

                List <Guid> lstProfileID = lstProfileQuery.Select(m => m.ID).ToList <Guid>();
                List <Att_AnnualLeaveDetailEntity> lstAnnDetail = repoAtt_AnnualLeaveDetail
                                                                  .FindBy(m => m.IsDelete == null && m.Type == E_INSURANCE_LEAVE && m.Year == Year &&
                                                                          m.ProfileID != null && lstProfileID.Contains(m.ProfileID.Value)).ToList().Translate <Att_AnnualLeaveDetailEntity>();
                return(lstAnnDetail);
            }
        }
        /// <summary>
        /// Button Tìm Kiếm Trong Phân Tích BHXH
        /// </summary>
        /// <param name="Year"></param>
        /// <param name="orgStructure"></param>
        /// <param name="LstProfileStatus"></param>
        /// <returns></returns>
        public List<Att_AnnualLeaveDetailEntity> SearchAnnualInsuranceLeaveDetail(int Year, string orgStructure, string LstProfileStatus,string UserLogin)
        {
            using (var context = new VnrHrmDataContext())
            {
                string status = string.Empty;
                var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                var repoAtt_AnnualLeaveDetail = new CustomBaseRepository<Att_AnnualLeaveDetail>(unitOfWork);

                List<object> lstObj = new List<object>();
                lstObj.Add(orgStructure);
                lstObj.Add(null);
                lstObj.Add(null);
                var lstProfileQuery = GetData<Hre_ProfileEntity>(lstObj, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, UserLogin, ref status).ToList();

                string E_INSURANCE_LEAVE = AnnualLeaveDetailType.E_INSURANCE_LEAVE.ToString();

                List<Guid> lstProfileID = lstProfileQuery.Select(m => m.ID).ToList<Guid>();
                List<Att_AnnualLeaveDetailEntity> lstAnnDetail = repoAtt_AnnualLeaveDetail
                    .FindBy(m => m.IsDelete == null && m.Type == E_INSURANCE_LEAVE && m.Year == Year
                    && m.ProfileID != null && lstProfileID.Contains(m.ProfileID.Value)).ToList().Translate<Att_AnnualLeaveDetailEntity>();
                return lstAnnDetail;
            }
        }
Beispiel #38
0
        public int[] SetPayrmentOut(List <Guid> SelectIds, DateTime MonthYear)
        {
            using (var context = new VnrHrmDataContext())
            {
                try
                {
                    var    unitOfWork                     = (IUnitOfWork)(new UnitOfWork(context));
                    string status                         = string.Empty;
                    var    repoKai_KaizenData             = new CustomBaseRepository <Kai_KaizenData>(unitOfWork);
                    List <Kai_KaizenData> ListKaiZendData = repoKai_KaizenData.FindBy(m => m.IsDelete != true && m.Status == EnumDropDown.Kai_KaizenDataStatus.E_APPROVED.ToString()).ToList();
                    ListKaiZendData = ListKaiZendData.Where(m => SelectIds.Any(t => t == m.ID)).ToList();

                    int Pass = 0;
                    int Fail = 0;

                    foreach (var i in ListKaiZendData)
                    {
                        if (i.IsPaymentOut == null && i.DateTransferPayment == null)
                        {
                            i.IsPaymentOut        = true;
                            i.DateTransferPayment = MonthYear;
                            Pass++;
                        }
                        else
                        {
                            Fail++;
                        }
                    }
                    unitOfWork.SaveChanges();
                    return(new int[] { Pass, Fail });
                }
                catch
                {
                    return(new int[] { 0, 0 });
                }
            }
        }
        /// <summary>
        /// [Hieu.Van]
        /// Xử lý Từ Chối
        /// </summary>
        /// <param name="LoginID"></param>
        /// <param name="userApprovedID"></param>
        /// <param name="recordID"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public string ProcessReject(string host, Guid LoginID, Guid recordID, string type)
        {
            DataErrorCode status = DataErrorCode.Success;

            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoFIN_PurchaseRequest = new CustomBaseRepository <FIN_PurchaseRequest>(unitOfWork);
                var repoSys_UserApprove     = new CustomBaseRepository <Sys_UserApprove>(unitOfWork);
                var repoSys_UserInfo        = new CustomBaseRepository <Sys_UserInfo>(unitOfWork);

                var record = repoFIN_PurchaseRequest.FindBy(s => s.ID == recordID).FirstOrDefault();
                if (record.Status == EnumDropDown.Status.E_REJECTED.ToString())
                {
                    return(DataErrorCode.Error_Reject.ToString());
                }
                var userApproved = repoSys_UserApprove.FindBy(s => s.ID == record.UserApproveID).FirstOrDefault();
                // Kiểm tra tài khoản login có được phép Duyệt hay ko?
                if (LoginID == Guid.Empty || userApproved.UserApproveID != LoginID)
                {
                    // kiểm tra nếu bản ghi có tk duyệt trống (tức bản ghi mới tạo) và tk login = tk tạo thì cho duyệt tiếp tục
                    if (record.UserApproveID == null && record.UserCreateID == LoginID)
                    {
                    }
                    else
                    {
                        return(DataErrorCode.NoPermission.ToString());
                    }
                }

                record.Status = EnumDropDown.Status.E_REJECTED.ToString();
                repoFIN_PurchaseRequest.Edit(record);
                status = repoFIN_PurchaseRequest.SaveChanges();

                return(status.ToString());
            }
        }
Beispiel #40
0
        public int[] SetPayrmentOut(List<Guid> SelectIds, DateTime MonthYear)
        {
            using (var context = new VnrHrmDataContext())
            {
                try
                {
                    var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                    string status = string.Empty;
                    var repoKai_KaizenData = new CustomBaseRepository<Kai_KaizenData>(unitOfWork);
                    List<Kai_KaizenData> ListKaiZendData = repoKai_KaizenData.FindBy(m => m.IsDelete != true && m.Status == EnumDropDown.Kai_KaizenDataStatus.E_APPROVED.ToString()).ToList();
                    ListKaiZendData = ListKaiZendData.Where(m => SelectIds.Any(t => t == m.ID)).ToList();

                    int Pass = 0;
                    int Fail = 0;

                    foreach (var i in ListKaiZendData)
                    {
                        if (i.IsPaymentOut == null && i.DateTransferPayment == null)
                        {
                            i.IsPaymentOut = true;
                            i.DateTransferPayment = MonthYear;
                            Pass++;
                        }
                        else
                        {
                            Fail++;
                        }
                    }
                    unitOfWork.SaveChanges();
                    return new int[] { Pass, Fail };
                }
                catch
                {
                    return new int[] { 0, 0 };
                }
            }
        }
        public Hashtable ComputeSalGroup(IUnitOfWork unitOfWork, DateTime monthYear, List<Sal_SalaryDepartment> lstSalDep, List<Sal_SalaryDepartmentItem> lstSalDepItem, ref List<Sal_SalaryDepartmentItem> lstItemDelete,
                                         DateTime DateStart, DateTime DateEnd, List<Cat_OrgStructure> listOrg)
        {
                #region Query Data

                Hashtable htSalGroup = new Hashtable();
                //Nhân viên
                var reposProfile = new CustomBaseRepository<Hre_Profile>(unitOfWork);

                //Nhân viên
                var reposSalaryDepartmentItem = new CustomBaseRepository<Sal_SalaryDepartmentItem>(unitOfWork);

                //Bảng công
                var reposAttendanceTb = new CustomBaseRepository<Att_AttendanceTable>(unitOfWork);

                //Bảng công chi tiết
                var reposAttendanceTbItem = new CustomBaseRepository<Att_AttendanceTableItem>(unitOfWork);

                //Ca làm việc
                var reposAttRoster = new CustomBaseRepository<Att_Roster>(unitOfWork);

                //Lương cơ bản
                var reposBasicSalary = new CustomBaseRepository<Sal_BasicSalary>(unitOfWork);

                //Chế độ lương
                var reposSalGrade = new CustomBaseRepository<Sal_Grade>(unitOfWork);
                #endregion

                foreach (Sal_SalaryDepartment salDep in lstSalDep)
                {
                    List<Sal_SalaryDepartmentItem> rsDepItem = new List<Sal_SalaryDepartmentItem>();
                    DateStart = salDep.DateFrom != null ? salDep.DateFrom.Value : DateStart;
                    DateEnd = salDep.DateTo != null ? salDep.DateTo.Value : DateEnd;

                    List<Guid> guidPro = new List<Guid>();
                    List<Guid> guidOrgAllChild = new List<Guid>();
                    List<Att_Roster> lstRosterLine = new List<Att_Roster>();

                    #region Lấy danh sách nhân viên trong phòng ban hoặc chuyền
                    if (salDep.TypeCompute == MethodComputeGroupSalary.E_COMPUTE_LINE.ToString())
                    {
                        lstRosterLine = reposAttRoster.FindBy(rs => rs.ProductionLineID == salDep.ProductionLineID &&
                                                              rs.IsDelete == null && rs.DateStart <= DateEnd && rs.DateEnd >= DateStart).ToList();
                        guidPro = lstRosterLine.Select(wh => wh.ProfileID).ToList();
                    }
                    else
                    {
                        if (salDep.OrgStructureID == null)
                            continue;
                        List<Cat_OrgStructure> lstChildsStructure = null;
                        Cat_OrgStructure DepartmentFilter = listOrg.FirstOrDefault(p => p.ID == salDep.OrgStructureID);
                        if (DepartmentFilter != null)
                            lstChildsStructure = GetChilds(listOrg, DepartmentFilter.ID);
                        else
                            lstChildsStructure = listOrg.Where(o => o.ID == salDep.OrgStructureID && o.IsDelete == null).ToList();
                        guidOrgAllChild = lstChildsStructure.Select(s => s.ID).Distinct().ToList();

                        //Lấy tất cả ID nhân viên trong các phòng ban trên.
                        guidPro = reposProfile.FindBy(hr => hr.IsDelete == null && guidOrgAllChild.Contains(hr.OrgStructureID.Value)).Select(hr => hr.ID).ToList();
                    }
                    #endregion

                    //Danh sách NV bao gồm các trạng thái (new, edit, fix, remove)
                    string stNEW = EnumDropDown.StatusLoadEnumSalDepartItem.E_NEW.ToString();
                    string stEDIT = EnumDropDown.StatusLoadEnumSalDepartItem.E_EDIT.ToString();
                    string stREMOVE = EnumDropDown.StatusLoadEnumSalDepartItem.E_REMOVE.ToString();
                    string stFIX = EnumDropDown.StatusLoadEnumSalDepartItem.E_FIX.ToString();
                    string stEDIT_FIX = EnumDropDown.StatusLoadEnumSalDepartItem.E_EDIT_FIX.ToString();
                    string[] strStatus = new string[] { stNEW, stREMOVE, stEDIT, stFIX, stEDIT_FIX };

                    var lstSalDepItemStatus = lstSalDepItem.Where(st => st.SalaryDepartmentID == salDep.ID && !String.IsNullOrEmpty(st.Status) && strStatus.Contains(st.Status)).ToList();
                    List<Guid> lstProAdd = new List<Guid>();
                    List<Guid> lstProFix = new List<Guid>();
                    List<Guid> lstProEdit = new List<Guid>();
                    List<Sal_SalaryDepartmentItem> lstItemRemove = new List<Sal_SalaryDepartmentItem>();

                    if (lstSalDepItemStatus.Count > 0)
                    {
                        #region LẤY RA DS NHÂN VIÊN VỚI CÁC TRẠNG THÁI
                        //Nếu tồn tại nhân viên là Fix, thì sẽ chỉ tính những profile có trạng thái fix, bỏ qua các trạng thái khác.
                        //Bổ sung thêm trạng thái Edit_Fix
                        lstProFix = lstSalDepItemStatus.Where(st => st.Status == stFIX || st.Status == stEDIT_FIX).Select(st => st.ProfileID).ToList();

                        //Lấy danh sách NV ko phải trạng thái fix trong departmentitem để xóa đi ( vì chỉ tính lương cho NV có Fix)
                        List<Sal_SalaryDepartmentItem> lstSalDepItemStatusNotFix = lstSalDepItem.Where(st => st.SalaryDepartmentID == salDep.ID && st.IsDelete == null).ToList();
                        lstSalDepItemStatusNotFix = lstSalDepItemStatusNotFix.Where(st => st.Status == null || (st.Status != stFIX && st.Status != stEDIT_FIX)).ToList();

                        if (lstProFix != null && lstProFix.Count > 0)
                        {
                            //Lấy những nhân viên không phải là Fix đưa vào trong lstItemDelete để xóa đi.
                            if (lstSalDepItemStatusNotFix.Count > 0)
                                lstItemDelete.AddRange(lstSalDepItemStatusNotFix);

                            //Chỉ add những nhân viên có Fix vào để tính.
                            guidPro.Clear();
                            foreach (Guid id in lstProFix)
                            {
                                guidPro.Add(id);
                            }
                        }
                        //Nếu ko có nhân viên nào là Fix, bắt đầu kiểm tra: New, edit, remove
                        else
                        {
                            //New
                            lstProAdd = lstSalDepItemStatus.Where(st => st.Status == stNEW).Select(st => st.ProfileID).ToList();
                            foreach (Guid id in lstProAdd)
                            {
                                if (!guidPro.Contains(id))
                                    guidPro.Add(id);
                            }

                            //Edit
                            lstProEdit = lstSalDepItemStatus.Where(st => st.Status == stEDIT).Select(st => st.ProfileID).ToList();
                            foreach (Guid id in lstProEdit)
                            {
                                if (!guidPro.Contains(id))
                                    guidPro.Add(id);
                            }

                            //Remove
                            lstItemRemove = lstSalDepItemStatus.Where(st => st.Status == stREMOVE).ToList();
                            List<Guid> lstProRemove = lstItemRemove.Select(st => st.ProfileID).ToList();
                            foreach (Guid id in lstProRemove)
                            {
                                if (guidPro.Contains(id))
                                    guidPro.Remove(id);
                            }
                        }
                        #endregion
                    }

                    //Lấy grade theo ds nhân viên
                    var lstGradeAll = reposSalGrade.FindBy(gr => gr.IsDelete == null && guidPro.Contains(gr.ProfileID)).ToList();

                    //Lấy Lương cơ bản theo ds nhân viên
                    var lstBasicSal = reposBasicSalary.FindBy(sal => sal.IsDelete == null && sal.DateOfEffect <= DateEnd && guidPro.Contains(sal.ProfileID)).ToList(); 

                    //Lấy roster theo ds nhân viên
                    var lstAllRoster = reposAttRoster.FindBy(rs => guidPro.Contains(rs.ProfileID) && rs.IsDelete == null && rs.DateStart <= DateEnd && rs.DateEnd >= DateStart)
                                                     .Select(rs => new { rs.ID, rs.ProfileID, rs.DateStart, rs.DateEnd, rs.SalaryType, rs.Cat_Shift }).ToList();
                    //Lấy bảng công theo ds nv
                    var lstAttAtendance = reposAttendanceTb.FindBy(att => att.IsDelete == null && att.MonthYear == monthYear && guidPro.Contains(att.ProfileID)).ToList();
                    var lstAttAtendanceID = lstAttAtendance.Select(att => att.ID).ToList();

                    //Lấy bảng công chi tiết
                    var lstAttAttendanceItem = reposAttendanceTbItem.FindBy(it => it.IsDelete == null && lstAttAtendanceID.Contains(it.AttendanceTableID)).ToList();

                    //Sau khi tiến hành các bước trên, sẽ có 1 danh sách nhân viên cuối cùng để xử lý.
                    var lstProfileOrg = reposProfile.FindBy(hr => guidPro.Contains(hr.ID)).ToList();

                    #region " Nếu tồn tại trạng thái Fix"
                    if (lstProFix != null && lstProFix.Count > 0)
                    {
                        foreach (Hre_Profile _pro in lstProfileOrg)
                        {
                            //Trạng thái: EDIT_FIX
                            //Những nhân viên đã được cố định và chỉnh sửa: Hệ số, giờ làm việc, OT thì sẽ lưu lại trong sal_departmentitem, và sẽ được lấy lên từ đây để tính, ko thông qua basicsalary nữa.
                            Sal_SalaryDepartmentItem itemProEditFix = new Sal_SalaryDepartmentItem();
                            if (lstProFix.Contains(_pro.ID))
                            {
                                itemProEditFix = lstSalDepItem.Where(it => it.ProfileID == _pro.ID && it.SalaryDepartmentID == salDep.ID &&
                                                                           it.Status == stEDIT_FIX).FirstOrDefault();
                                if (itemProEditFix != null)
                                {
                                    rsDepItem.Add(itemProEditFix);
                                    continue;
                                }
                            }

                            Sal_SalaryDepartmentItem itemProFix = new Sal_SalaryDepartmentItem(); ;
                            itemProFix = lstSalDepItem.Where(it => it.ProfileID == _pro.ID && it.SalaryDepartmentID == salDep.ID && it.Status == stFIX).FirstOrDefault();

                            #region Ver8 chưa dùng
                            //Sal_Grade grade = GradeDAO.GetGrade(lstGradeAll, _pro.ID, DateEnd);
                            //if (grade == null)
                            //{
                            //    continue;
                            //}
                            //Cat_GradeCfg gradeCfg = lstGradeCfg.Where(gra => gra.ID == grade.GradeID).FirstOrDefault();
                            //if (gradeCfg == null || gradeCfg.Formula != enumFomula)
                            //    continue;
                            //AttendanceService.GetSalaryDateRange(gradeCfg, sys_AppConfig, null, monthYear, out DateStart, out DateEnd);
                            //if (salDep.DateFrom != null && salDep.DateFrom.Value >= DateStart && salDep.DateFrom.Value <= DateEnd)
                            //{
                            //    DateStart = salDep.DateFrom.Value;
                            //}
                            //if (salDep.DateTo != null && salDep.DateTo.Value >= DateStart && salDep.DateTo.Value <= DateEnd)
                            //{
                            //    DateEnd = salDep.DateTo.Value;
                            //}
                            #endregion

                            //dữ liệu công
                            var _att = lstAttAtendance.Where(att => att.ProfileID == _pro.ID).Select(att => new { att.ID }).FirstOrDefault();
                            if (_att == null)
                                continue;
                            var _attLstItem1 = lstAttAttendanceItem.Where(at => at.AttendanceTableID == _att.ID).ToList();

                            List<Att_AttendanceTableItem> _attLstItem = new List<Att_AttendanceTableItem>();
                            #region Xử lý trường hợp 1 tháng có 2 cách tính lương ( lương bộ phận và lương thời gian). Vì vậy cần kiểm tra roster để lấy công cho phù hợp.
                            if (lstAllRoster.Count > 0)
                            {
                                var roster = lstAllRoster.Where(ro => ro.ProfileID == _pro.ID && ro.DateStart.Year == monthYear.Year
                                                                                              && ro.DateEnd.Month >= monthYear.Month && ro.DateStart.Month <= monthYear.Month
                                                                                              && ro.SalaryType != null && ro.SalaryType == SalaryRosterType.E_DEPTSAL.ToString()).FirstOrDefault();
                                if (roster != null && roster.Cat_Shift != null)
                                {
                                    _attLstItem = _attLstItem1.Where(it => it.ShiftID.HasValue && it.ShiftID.Value == roster.Cat_Shift.ID
                                                                                               && it.WorkDate >= roster.DateStart && it.WorkDate <= roster.DateEnd
                                                                                               && it.DutyCode == DutyCode.E_ON.ToString()).ToList();
                                }
                                else //Trừ bớt các ngày công là timesal
                                {
                                    var rostertimesal = lstAllRoster.Where(ro => ro.ProfileID == _pro.ID && ro.DateStart.Year == monthYear.Year
                                                                                                         && ro.DateEnd.Month >= monthYear.Month && ro.DateStart.Month <= monthYear.Month
                                                                                                         && ro.SalaryType != null && ro.SalaryType == SalaryRosterType.E_TIMESAL.ToString()).FirstOrDefault();
                                    if (rostertimesal != null && rostertimesal.Cat_Shift != null)
                                    {
                                        List<Att_AttendanceTableItem> lstattitemtimesal = _attLstItem1.Where(it => it.ShiftID.HasValue && it.ShiftID.Value == rostertimesal.Cat_Shift.ID
                                                                                                             && it.WorkDate >= rostertimesal.DateStart && it.WorkDate <= rostertimesal.DateEnd
                                                                                                             && it.DutyCode == DutyCode.E_ON.ToString()).ToList();
                                        foreach (Att_AttendanceTableItem it in lstattitemtimesal)
                                        {
                                            if (it != null)
                                                _attLstItem1.Remove(it);
                                        }
                                    }
                                }
                            }
                            if (_attLstItem.Count < 1)
                                _attLstItem = _attLstItem1;
                            #endregion

                            List<Sal_BasicSalary> lstBasicSalPro = lstBasicSal.Where(sal => sal.ProfileID == _pro.ID).OrderByDescending(sal => sal.DateOfEffect).ToList();

                            //Xóa những nhân viên được Fix có lương cơ bản đã đc tính trước đó, để tính lại.
                            if (lstBasicSalPro != null && lstBasicSalPro.Count > 0)
                            {
                                List<Sal_SalaryDepartmentItem> lstItemFix = lstSalDepItem.Where(it => it.ProfileID == _pro.ID && it.SalaryDepartmentID == salDep.ID
                                                                            && (it.Status == stFIX
                                                                            || it.Status == stEDIT_FIX)).ToList();
                                if (lstItemFix != null && lstItemFix.Count > 0)
                                    lstItemDelete.AddRange(lstItemFix);
                            }

                            //Bắt đầu thêm giờ công, hệ số, giờ OT lần lượt cho từng người (XC 1.2)
                            if (salDep.TypeCompute == MethodComputeGroupSalary.E_COMPUTE_LINE.ToString())
                            {
                                List<Att_Roster> lstRosterPro = lstRosterLine.Where(rs => rs.ProfileID == _pro.ID).ToList();
                                rsDepItem.AddRange(CalSalaryLineItemProfile(salDep, _attLstItem, _pro, lstBasicSalPro, lstRosterPro, DateStart, DateEnd, monthYear, itemProFix));
                            }
                            else
                            {
                                rsDepItem.AddRange(CalSalaryDepartmentItemProfile(salDep, _attLstItem, _pro, lstBasicSalPro, DateStart, DateEnd, monthYear, itemProFix));
                            }
                        }
                    }
                    #endregion
                    #region " Không tồn tại trạng thái Fix"
                    else
                    {
                        //test
                        //lstProfileOrg = lstProfileOrg.Where(hr => hr.CodeEmp == "VPM183").ToList();
                        //end test
                        foreach (Hre_Profile _pro in lstProfileOrg)
                        {
                            //Trạng thái: NEW
                            //Những nhân viên trong trạng thái này sẽ ko thuộc phòng ban hoặc chuyền ban đầu. Khi đó các hệ số, giờ làm việc, OT sẽ được thêm vào và lưu trong sal_departmentitem
                            Sal_SalaryDepartmentItem itemProAdd = new Sal_SalaryDepartmentItem();
                            if (lstProAdd.Contains(_pro.ID))
                            {
                                itemProAdd = lstSalDepItem.Where(it => it.ProfileID == _pro.ID && it.SalaryDepartmentID == salDep.ID &&
                                                                       it.Status == stNEW).FirstOrDefault();
                                rsDepItem.Add(itemProAdd);
                                continue;
                            }

                            //Trạng thái: EDIT
                            //Những nhân viên đã được chỉnh sửa: Hệ số, giờ làm việc, OT thì sẽ lưu lại trong sal_departmentitem, và sẽ được lấy lên từ đây để tính, ko thông qua basicsalary nữa.
                            if (lstProEdit.Contains(_pro.ID))
                            {
                                itemProAdd = lstSalDepItem.Where(it => it.ProfileID == _pro.ID && it.SalaryDepartmentID == salDep.ID &&
                                                                       it.Status == stEDIT).FirstOrDefault();
                                rsDepItem.Add(itemProAdd);
                                continue;
                            }

                            #region Ver8 chưa dùng
                            //Sal_Grade grade = GradeDAO.GetGrade(lstGradeAll, _pro.ID, DateEnd);
                            //if (grade == null)
                            //{
                            //    continue;
                            //}
                            //Cat_GradeCfg gradeCfg = lstGradeCfg.Where(gra => gra.ID == grade.GradeID).FirstOrDefault();
                            //if (gradeCfg == null || gradeCfg.Formula != enumFomula)
                            //    continue;
                            //List<Sal_SalaryDepartmentItem> lstItemPro = lstSalDepItem.Where(it => it.ProfileID == _pro.ID && it.SalaryDepartmentID == salDep.ID
                            //                                            && (String.IsNullOrEmpty(it.Status) || !strStatus.Contains(it.Status))).ToList();
                            //lstItemDelete.AddRange(lstItemPro);

                            //AttendanceService.GetSalaryDateRange(gradeCfg, sys_AppConfig, null, monthYear, out DateStart, out DateEnd);
                            //if (salDep.DateFrom != null && salDep.DateFrom.Value >= DateStart && salDep.DateFrom.Value <= DateEnd)
                            //{
                            //    DateStart = salDep.DateFrom.Value;
                            //}
                            //if (salDep.DateTo != null && salDep.DateTo.Value >= DateStart && salDep.DateTo.Value <= DateEnd)
                            //{
                            //    DateEnd = salDep.DateTo.Value;
                            //}
                            #endregion

                            //dữ liệu công
                            var _att = lstAttAtendance.Where(att => att.ProfileID == _pro.ID).Select(att => new { att.ID }).FirstOrDefault();
                            if (_att == null)
                                continue;
                            var _attLstItem1 = lstAttAttendanceItem.Where(at => at.AttendanceTableID == _att.ID).ToList();

                            List<Att_AttendanceTableItem> _attLstItem = new List<Att_AttendanceTableItem>();
                            #region Xử lý trường hợp 1 tháng có 2 cách tính lương ( lương bộ phận và lương thời gian). Vì vậy cần kiểm tra roster để lấy công cho phù hợp.
                            if (lstAllRoster.Count > 0)
                            {
                                var roster = lstAllRoster.Where(ro => ro.ProfileID == _pro.ID && ro.DateStart.Year == monthYear.Year
                                                                                              && ro.DateEnd.Month >= monthYear.Month && ro.DateStart.Month <= monthYear.Month
                                                                                              && ro.SalaryType != null && ro.SalaryType == SalaryRosterType.E_DEPTSAL.ToString()).FirstOrDefault();
                                if (roster != null && roster.Cat_Shift != null)
                                {
                                    _attLstItem = _attLstItem1.Where(it => it.ShiftID.HasValue && it.ShiftID.Value == roster.Cat_Shift.ID
                                                                                               && it.WorkDate >= roster.DateStart && it.WorkDate <= roster.DateEnd
                                                                                               && it.DutyCode == DutyCode.E_ON.ToString()).ToList();
                                }
                                else //Trừ bớt các ngày công là timesal
                                {
                                    var rostertimesal = lstAllRoster.Where(ro => ro.ProfileID == _pro.ID && ro.DateStart.Year == monthYear.Year
                                                                                                         && ro.DateEnd.Month >= monthYear.Month && ro.DateStart.Month <= monthYear.Month
                                                                                                         && ro.SalaryType != null && ro.SalaryType == SalaryRosterType.E_TIMESAL.ToString()).FirstOrDefault();
                                    if (rostertimesal != null && rostertimesal.Cat_Shift != null)
                                    {
                                        List<Att_AttendanceTableItem> lstattitemtimesal = _attLstItem1.Where(it => it.ShiftID.HasValue && it.ShiftID.Value == rostertimesal.Cat_Shift.ID
                                                                                                             && it.WorkDate >= rostertimesal.DateStart && it.WorkDate <= rostertimesal.DateEnd
                                                                                                             && it.DutyCode == DutyCode.E_ON.ToString()).ToList();
                                        foreach (Att_AttendanceTableItem it in lstattitemtimesal)
                                        {
                                            if (it != null)
                                                _attLstItem1.Remove(it);
                                        }
                                    }
                                }
                            }
                            if (_attLstItem.Count < 1)
                                _attLstItem = _attLstItem1;
                            #endregion

                            List<Sal_BasicSalary> lstBasicSalPro = lstBasicSal.Where(sal => sal.ProfileID == _pro.ID).OrderByDescending(sal => sal.DateOfEffect).ToList();

                            //Bắt đầu thêm giờ công, hệ số, giờ OT lần lượt cho từng người (XC 1.2)
                            if (salDep.TypeCompute == MethodComputeGroupSalary.E_COMPUTE_LINE.ToString())
                            {
                                List<Att_Roster> lstRosterPro = lstRosterLine.Where(rs => rs.ProfileID == _pro.ID).ToList();
                                rsDepItem.AddRange(CalSalaryLineItemProfile(salDep, _attLstItem, _pro, lstBasicSalPro, lstRosterPro, DateStart, DateEnd, monthYear, itemProAdd));
                            }
                            else
                            {
                                rsDepItem.AddRange(CalSalaryDepartmentItemProfile(salDep, _attLstItem, _pro, lstBasicSalPro, DateStart, DateEnd, monthYear, itemProAdd));
                            }
                        }
                    }
                    #endregion

                    //Trả về 0 các trạng thái REMOVE đã tính lần đầu
                    lstItemRemove.ForEach(it => it.AmoutSalary = 0);

                    //Tính toán tiền lương và các loại tiền OT (XC Finished)
                    ComputeAmountPro(rsDepItem, salDep);
                    foreach (var t in rsDepItem)
                    {
                        t.ID = Guid.NewGuid();
                        reposSalaryDepartmentItem.Add(t);
                    }
                    //View lên lưới những nhân viên đã chuyển qua trạng thái là E_REMOVE.
                    //Mục đích: Nếu muốn tính lại cho những NV này thì edit chuyển trạng thái lại để tính.
                    rsDepItem.AddRange(lstItemRemove);

                    htSalGroup.Add(salDep, rsDepItem);
                }
                return htSalGroup;
        }
Beispiel #42
0
        //private static Thread threadCompute;

        /// <summary>
        /// Tính giữ lương
        /// </summary>
        /// <param name="listProfileIds">Id bảng HoldSalary</param>
        /// <param name="CutoffdurationID">Kỳ tính lương</param>
        /// <returns></returns>
        public ResultsObject ComputeHoldSalary(List<Guid> listHoldSalaryIDs, Guid CutoffdurationID, string UserLogin)
        {
            try
            {
                Sys_AttOvertimePermitConfigServices Sys_Services = new Sys_AttOvertimePermitConfigServices();
                string elementBeforeTax = Sys_Services.GetConfigValue<string>(AppConfig.HRM_SAL_HOLDSALARY_ELEMENT);
                string elementAfterTax = Sys_Services.GetConfigValue<string>(AppConfig.HRM_SAL_HOLDSALARY_ELEMENT_AFTERTAX);
                //Nếu chưa có config thì out
                if (string.IsNullOrEmpty(elementBeforeTax) || string.IsNullOrEmpty(elementAfterTax))
                {
                    return new ResultsObject() { Success = false, Messenger = ConstantDisplay.HRM_Sal_HoldSalary_ConfigElementHoldSalary.TranslateString() };
                }

                using (var context = new VnrHrmDataContext())
                {
                    string status = string.Empty;
                    var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                    var repoSys_AsynTask = new CustomBaseRepository<Sys_AsynTask>(unitOfWork);
                    var repoAtt_CutOffDuration = new CustomBaseRepository<Att_CutOffDuration>(unitOfWork);
                    var repoSal_HoldSalary = new CustomBaseRepository<Sal_HoldSalary>(unitOfWork);
                    var repoHre_Profile = new CustomBaseRepository<Hre_ProfileEntity>(unitOfWork);
                    var repoPayrollTable = new CustomBaseRepository<Sal_PayrollTable>(unitOfWork);
                    var payrollTableItem = new CustomBaseRepository<Sal_PayrollTableItem>(unitOfWork);
                    #region Get data
                    List<object> listModel = new List<object>();
                    listModel.AddRange(new object[3]);
                    listModel[1] = 1;
                    listModel[2] = Int32.MaxValue - 1;
                    List<Att_CutOffDurationEntity> listCutoffduration_All = GetData<Att_CutOffDurationEntity>(listModel, ConstantSql.hrm_att_sp_get_CutOffDurations, UserLogin, ref status).ToList();

                    listModel = new List<object>();
                    listModel.AddRange(new object[5]);
                    listModel[3] = 1;
                    listModel[4] = Int32.MaxValue - 1;
                    List<Sal_HoldSalary> listHoldSalary = repoSal_HoldSalary.FindBy(m => m.IsDelete != true && m.Terminate != true).ToList();
                    listHoldSalary = listHoldSalary.Where(m => listHoldSalaryIDs.Any(t => t == m.ID)).ToList();

                    listModel = new List<object>();
                    listModel.AddRange(new object[7]);
                    listModel[5] = 1;
                    listModel[6] = Int32.MaxValue - 1;
                    List<Cat_ElementEntity> listElement = GetData<Cat_ElementEntity>(listModel, ConstantSql.hrm_cat_sp_get_Element_All, UserLogin, ref status);

                    listModel = new List<object>();
                    listModel.AddRange(new object[18]);
                    listModel[16] = 1;
                    listModel[17] = Int32.MaxValue - 1;
                    List<Hre_ProfileEntity> listHre_profile = GetData<Hre_ProfileEntity>(listModel, ConstantSql.hrm_hr_sp_get_Profile, UserLogin, ref status).ToList();
                    #endregion

                    //Get byid cutoff
                    Att_CutOffDurationEntity CutoffdurationItem = listCutoffduration_All.Single(m => m.ID == CutoffdurationID);

                    //Lọc cutoff, chỉ lấy cutoff có tháng/năm lớn hơn tháng/năm của nhân viên bị giữ lương có ngày bắt đầu giữ lương nhỏ nhất
                    DateTime dateCutoff = new DateTime(CutoffdurationItem.MonthYear.Year, CutoffdurationItem.MonthYear.Month, 1);
                    var _tmp = listHoldSalary.FirstOrDefault().MonthSalary.Value;
                    DateTime dateFirstHold = new DateTime(_tmp.Year, _tmp.Month, 1);
                    List<Att_CutOffDurationEntity> listCutoffduration = listCutoffduration_All.Where(m => new DateTime(m.MonthYear.Year, m.MonthYear.Month, 1) >= dateFirstHold && new DateTime(m.MonthYear.Year, m.MonthYear.Month, 1) < dateCutoff).ToList();

                    //Get dữ liệu lập công thức
                    ComputePayrollDataModel TotalData = GetDataForComputeSalary(CutoffdurationItem, UserLogin);

                    //Biến lưu giá trị tính được qua từng tháng theo từng nhân viên
                    Dictionary<Guid, double[]> listAmountHoldSalary = new Dictionary<Guid, double[]>();

                    for (int i = 0; i < listCutoffduration.Count; i++)
                    {
                        //lấy lại các dữ liệu liên quan tới cutoff
                        TotalData = GetDataForComputeSalary_ForCutOff(TotalData, listCutoffduration[i], UserLogin);

                        //biến tạm lưu các nhân viên được tính kỳ đang duyệt qua
                        List<Sal_HoldSalary> listProfile_Any_Cutoff = new List<Sal_HoldSalary>();
                        listProfile_Any_Cutoff = listHoldSalary.Where(m => new DateTime(m.MonthSalary.Value.Year, m.MonthSalary.Value.Month, 1) <= new DateTime(listCutoffduration[i].MonthYear.Year, listCutoffduration[i].MonthYear.Month, 1)).ToList();

                        //bắt đầu tính qua từng nhân viên bị giữ lương trong tháng đang duyệt qua
                        for (int j = 0; j < listProfile_Any_Cutoff.Count; j++)
                        {
                            #region Tính công thức
                            //tính công thức
                            var listElementByConfigBeforeTax = listElement.FirstOrDefault(m => m.ElementCode == elementBeforeTax);
                            var listElementByConfigAfterTax = listElement.FirstOrDefault(m => m.ElementCode == elementAfterTax);
                            List<Cat_ElementEntity> ListElement = new List<Cat_ElementEntity>();
                            ListElement.Add(listElementByConfigBeforeTax);
                            ListElement.Add(listElementByConfigAfterTax);
                            List<ElementFormula> listElementFormula = new List<ElementFormula>();
                            listElementFormula = ParseElementFormula(listElementFormula, ListElement, TotalData, listHre_profile.Single(m => m.ID == listProfile_Any_Cutoff[j].ProfileID), listCutoffduration[i], new Dictionary<Guid, ValueCount>(), false, new TraceLogManager());

                            //lưu vài biến tổng
                            if (listElementFormula != null)
                            {
                                if (listAmountHoldSalary.Any(m => m.Key == listProfile_Any_Cutoff[j].ID))
                                {
                                    listAmountHoldSalary[listProfile_Any_Cutoff[j].ID][0] += double.Parse(listElementFormula.FirstOrDefault(m => m.VariableName == listElementByConfigBeforeTax.ElementCode).Value.ToString());
                                    listAmountHoldSalary[listProfile_Any_Cutoff[j].ID][1] += double.Parse(listElementFormula.FirstOrDefault(m => m.VariableName == listElementByConfigAfterTax.ElementCode).Value.ToString());
                                }
                                else
                                {
                                    var ElementByConfigBeforeTax = listElementFormula.FirstOrDefault(m => m.VariableName == listElementByConfigBeforeTax.ElementCode);
                                    var ElementByConfigAfterTax = listElementFormula.FirstOrDefault(m => m.VariableName == listElementByConfigAfterTax.ElementCode);

                                    listAmountHoldSalary.Add(listProfile_Any_Cutoff[j].ID, new double[] { double.Parse(ElementByConfigBeforeTax.Value.ToString()), 0 });

                                    listAmountHoldSalary[listProfile_Any_Cutoff[j].ID][1] = double.Parse(ElementByConfigAfterTax.Value.ToString());
                                }
                            }
                            #endregion
                        }
                    }

                    for (int i = 0; i < listHoldSalary.Count; i++)
                    {
                        listHoldSalary[i].MonthEndSalary = CutoffdurationItem.MonthYear;
                        if (listAmountHoldSalary.Any(m => m.Key == listHoldSalary[i].ID))
                        {
                            listHoldSalary[i].AmountSalary = listAmountHoldSalary[listHoldSalary[i].ID][0];
                            listHoldSalary[i].AmountSalaryAfterTax = listAmountHoldSalary[listHoldSalary[i].ID][1];
                        }
                        else
                        {
                            listHoldSalary[i].AmountSalary = null;
                            listHoldSalary[i].AmountSalaryAfterTax = null;
                        }
                    }
                    unitOfWork.SaveChanges();
                    return new ResultsObject();
                }
            }
            catch (Exception ex)
            {
                return new ResultsObject() { Success = false, Messenger = ex.Message };
            }
        }
Beispiel #43
0
        /// <summary>
        /// Compute Payroll New
        /// </summary>
        /// <param name="ProfileID"></param>
        /// <param name="CutOffDuration"></param>
        /// <param name="Sys_AsynTaskID"></param>
        public void ComputePayroll_Progress(ComputePayrollDataModel TotalData, List<Hre_ProfileEntity> ProfileID, Att_CutOffDurationEntity CutOffDuration, Guid Sys_AsynTaskID, int totalProfile, TraceLogManager FileLog, bool ComputeOrderNumber, bool Settlement = false)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = new UnitOfWork(context);
                DateTime DatetimeStart = new DateTime();

                #region Init Repo
                var repoSys_AsynTask = new CustomBaseRepository<Sys_AsynTask>(unitOfWork);
                var repoHre_profile = new CustomBaseRepository<Hre_ProfileEntity>(unitOfWork);
                var repoCat_Element = new CustomBaseRepository<Cat_ElementEntity>(unitOfWork);
                var repoSal_BasicSalary = new CustomBaseRepository<Sal_BasicSalaryEntity>(unitOfWork);
                //var repoPayrollTable = new CustomBaseRepository<Sal_PayrollTable>(unitOfWork);
                //var repoPayrollTableItem = new CustomBaseRepository<Sal_PayrollTableItem>(unitOfWork);

                var repoCat_OvertimeType = new CustomBaseRepository<Cat_OvertimeTypeEntity>(unitOfWork);
                var repoCat_LeaveDayType = new CustomBaseRepository<Cat_LeaveDayTypeEntity>(unitOfWork);
                var repoCat_UsualAllowanceEntity = new CustomBaseRepository<Cat_UsualAllowanceEntity>(unitOfWork);
                var repoCat_GradePayroll = new CustomBaseRepository<Cat_GradePayrollEntity>(unitOfWork);
                var repoCat_UnusualAllowanceCfg = new CustomBaseRepository<Cat_UnusualAllowanceCfgEntity>(unitOfWork);
                var repoSal_PayrollTable = new CustomBaseRepository<Sal_PayrollTable>(unitOfWork);
                #endregion

                //Các biến xử dụng chung
                Sys_AsynTask asynTask = new Sys_AsynTask();

                //[SCV] list lưu tiền khấu nhân viên chưa đủ thâm niên của shop
                Dictionary<Guid, ValueCount> listTmpDeduction = new Dictionary<Guid, ValueCount>();
                List<Sal_PayrollTableItem> listPayrollTableItem = new List<Sal_PayrollTableItem>();
                List<Sal_PayrollTable> listPayrollTable = new List<Sal_PayrollTable>();

                //Get asynTask
                asynTask = repoSys_AsynTask.FindBy(m => m.ID == Sys_AsynTaskID).FirstOrDefault();

                //Order By theo ngày vào làm để tính trường hợp nhân viên không đủ thâm niên của dự án SCV
                ProfileID = ProfileID.OrderBy(m => m.DateHire).ToList();
                ParallelOptions parallelOptions = new ParallelOptions();

                #region Duyệt Profile

                //Parallel.For(0, ProfileID.Count, parallelOptions, d =>
                //{

                //});

                for (int i = 0; i < ProfileID.Count; i++)
                {
                    TraceLogItemInfo logItem = new TraceLogItemInfo();
                    DatetimeStart = DateTime.Now;
                    var profileItem = ProfileID[i];
                    bool isCancled = false;

                    //Biến tổng lưu tất cả các value của Formula
                    List<ElementFormula> listElementFormula = new List<ElementFormula>();

                    //Lấy các phần tử tính lương nằm trong Grade của nhân viên
                    Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd);
                    List<Cat_ElementEntity> listElement = new List<Cat_ElementEntity>();
                    if (Grade.GradePayrollID != null && Grade.GradePayrollID != Guid.Empty)
                    {
                        listElement = new List<Cat_ElementEntity>(TotalData.listElement_All.Where(m => (m.GradePayrollID != null && (Guid)m.GradePayrollID == Grade.GradePayrollID) || m.IsApplyGradeAll == true));
                    }

                    //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương
                    Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault();
                    if (CatGrade != null && CatGrade.SalaryTimeTypeClose != null)
                    {
                        DateTime DateClose = new DateTime();
                        if (CatGrade.SalaryTimeTypeClose == SalaryTimeTypeClose.E_CURRENTMONTH.ToString())
                        {
                            DateClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose > 30 && CutOffDuration.MonthYear.Month % 2 == 0 ? 30 : (int)CatGrade.SalaryDayClose : 1);
                        }
                        else if (CatGrade.SalaryTimeTypeClose == SalaryTimeTypeClose.E_LASTMONTH.ToString())
                        {
                            DateClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose > 30 && CutOffDuration.MonthYear.Month % 2 == 0 ? 30 : (int)CatGrade.SalaryDayClose : 1).AddMonths(-1);
                        }

                        if (profileItem.DateHire != null && (DateTime)profileItem.DateHire > DateClose)
                        {
                            isCancled = true;
                            FileLog.WriteLog("NV có ngày vào làm sau ngày chốt lương của tháng", "", "");
                        }
                    }

                    if (!isCancled)
                    {
                        #region tạo mới PayrollTable
                        Sal_PayrollTable PayrollTable_Model = new Sal_PayrollTable();
                        if (Settlement == true)
                        {
                            if (repoSal_PayrollTable.FindBy(m => m.CutOffDurationID == CutOffDuration.ID && m.ProfileID == profileItem.ID).FirstOrDefault() != null)
                            {
                                Att_CutOffDurationEntity CutOff = TotalData.listCutOffDuration.Where(m => m.MonthYear >= CutOffDuration.MonthYear).OrderBy(m => m.MonthYear).FirstOrDefault();
                                PayrollTable_Model = new Sal_PayrollTable()
                                {
                                    ID = Guid.NewGuid(),
                                    ProfileID = profileItem.ID,
                                    CutOffDurationID = CutOff.ID,
                                    MonthYear = CutOff.MonthYear,
                                    OrgStructureID = profileItem.OrgStructureID,
                                    PositionID = profileItem.PositionID,
                                    JobTitleID = profileItem.JobTitleID,
                                    EmployeeTypeID = profileItem.EmpTypeID,
                                    PayrollGroupID = profileItem.PayrollGroupID,
                                    CostCentreID = profileItem.CostCentreID,
                                    IncomeBeforeTax = 0,
                                    IsCash = profileItem.IsCash,
                                    DependantCount = 0,
                                    IncomeTaxable = 0,
                                    AmountPaidPITCom = 0,
                                    AmountPaidPITEmp = 0,
                                    IncomeNET = 0,
                                    BankID = profileItem.BankID,
                                    AccountNo = profileItem.AccountNo,
                                    Status = FileLog.GetFullPath(FileLog.FileName).Replace(".XML", "_" + DateTime.Now.ToString("yyyyMMdd") + ".XML"),
                                };
                            }
                            else
                            {
                                PayrollTable_Model = new Sal_PayrollTable()
                                {
                                    ID = Guid.NewGuid(),
                                    ProfileID = profileItem.ID,
                                    CutOffDurationID = CutOffDuration.ID,
                                    MonthYear = CutOffDuration.MonthYear,
                                    OrgStructureID = profileItem.OrgStructureID,
                                    PositionID = profileItem.PositionID,
                                    JobTitleID = profileItem.JobTitleID,
                                    EmployeeTypeID = profileItem.EmpTypeID,
                                    PayrollGroupID = profileItem.PayrollGroupID,
                                    CostCentreID = profileItem.CostCentreID,
                                    IncomeBeforeTax = 0,
                                    DependantCount = 0,
                                    IncomeTaxable = 0,
                                    AmountPaidPITCom = 0,
                                    AmountPaidPITEmp = 0,
                                    IncomeNET = 0,
                                    BankID = profileItem.BankID,
                                    AccountNo = profileItem.AccountNo,
                                    Status = FileLog.GetFullPath(FileLog.FileName).Replace(".XML", "_" + DateTime.Now.ToString("yyyyMMdd") + ".XML"),
                                };
                            }
                        }
                        else
                        {
                            PayrollTable_Model = new Sal_PayrollTable()
                            {
                                ID = Guid.NewGuid(),
                                ProfileID = profileItem.ID,
                                CutOffDurationID = CutOffDuration.ID,
                                MonthYear = CutOffDuration.MonthYear,
                                OrgStructureID = profileItem.OrgStructureID,
                                PositionID = profileItem.PositionID,
                                JobTitleID = profileItem.JobTitleID,
                                EmployeeTypeID = profileItem.EmpTypeID,
                                PayrollGroupID = profileItem.PayrollGroupID,
                                CostCentreID = profileItem.CostCentreID,
                                IncomeBeforeTax = 0,
                                DependantCount = 0,
                                IncomeTaxable = 0,
                                AmountPaidPITCom = 0,
                                AmountPaidPITEmp = 0,
                                IncomeNET = 0,
                                BankID = profileItem.BankID,
                                AccountNo = profileItem.AccountNo,
                                //Status = FileLog.GetFullPath(FileLog.FileName).Replace(".XML", "_" + DateTime.Now.ToString("yyyyMMdd") + ".XML"),
                            };
                        }

                        lock (listPayrollTable)
                        {
                            listPayrollTable.Add(PayrollTable_Model);
                        }

                        #endregion

                        //bắt lỗi tính công thức có giá trị nào null hay không
                        try
                        {
                            //DatetimeStart = DateTime.Now;
                            listElementFormula = ParseElementFormula(listElementFormula, listElement, TotalData, profileItem, CutOffDuration, listTmpDeduction, ComputeOrderNumber, FileLog);
                            //FileLog.WriteLog("", "Compute Formula", Common.ComputeTime(DatetimeStart, DateTime.Now));

                            listElement = listElement.OrderBy(m => m.OrderNumber).ToList();//sắp xếp lại

                            //Duyệt qua các phần tử tính lương 
                            foreach (var elementItem in listElement)
                            {
                                Sal_PayrollTableItem tableItem = new Sal_PayrollTableItem();
                                tableItem.ID = Guid.NewGuid();
                                tableItem.PayrollTableID = PayrollTable_Model.ID;
                                tableItem.Name = elementItem.ElementName;
                                tableItem.Code = elementItem.ElementCode;
                                tableItem.MonthYear = CutOffDuration.MonthYear;
                                tableItem.IsDecrypt = false;
                                tableItem.IsAddToHourlyRate = false;
                                tableItem.IsChargePIT = false;
                                tableItem.OrderNo = elementItem.OrderNumber != null ? (int)elementItem.OrderNumber : 0;
                                tableItem.ElementType = elementItem.TabType;
                                tableItem.ValueType = elementItem.Type;
                                tableItem.IsShow = elementItem.Invisible != null ? !elementItem.Invisible : true;
                                if (elementItem.IsBold == true)
                                {
                                    tableItem.Description4 += "E_BOLD,";
                                }
                                tableItem.Description4 += elementItem.ElementLevel + "," + elementItem.Type;
                                var ElementResult = listElementFormula.Where(m => m.VariableName.Trim() == elementItem.ElementCode.Trim());
                                if (ElementResult != null)
                                {
                                    tableItem.Value = ElementResult.LastOrDefault().Value.ToString();
                                    tableItem.Description1 = ElementResult.LastOrDefault().ErrorMessage;
                                }
                                else
                                {
                                    tableItem.Value = "0";
                                    tableItem.Description1 = "Không Tìm Thấy Phần Tử !";
                                }

                                lock (listPayrollTableItem)
                                {
                                    listPayrollTableItem.Add(tableItem);
                                }
                            }
                            logItem.Summary += profileItem.CodeEmp + "-" + profileItem.ProfileName + "-" + Common.ComputeTime(DatetimeStart, DateTime.Now) + "-" + listElement.Count.ToString() + "Element Formula";
                            logItem.Source = "Sucess";
                            FileLog.WriteLog(logItem);
                        }
                        catch (Exception ex)
                        {
                            logItem.Summary += profileItem.CodeEmp + "-" + profileItem.ProfileName + "-" + Common.ComputeTime(DatetimeStart, DateTime.Now) + "-" + listElement.Count.ToString() + " Element Formula";
                            logItem.Description = ex.Message;
                            logItem.Source = "Error";
                            FileLog.WriteLog(logItem);
                            //FileLog.WriteLog("Error", "Error Compute Profle " + ProfileID[i].CodeEmp + "-" + ProfileID[i].ProfileName, Common.ComputeTime(DatetimeStart, DateTime.Now));

                            Sal_PayrollTableItem tableItem = new Sal_PayrollTableItem();
                            tableItem.ID = Guid.NewGuid();
                            tableItem.PayrollTableID = PayrollTable_Model.ID;
                            tableItem.Name = "Lỗi, không thể tính được phần tử " + ex.Message;
                            tableItem.Code = "Error";
                            tableItem.MonthYear = CutOffDuration.MonthYear;
                            tableItem.IsDecrypt = false;
                            tableItem.IsAddToHourlyRate = false;
                            tableItem.IsChargePIT = false;
                            tableItem.OrderNo = 0;
                            tableItem.ElementType = "Payroll";
                            tableItem.ValueType = "Double";
                            tableItem.Description4 = "Double";
                            tableItem.Value = "0";
                            tableItem.Description1 = ex.Message;

                            lock (listPayrollTableItem)
                            {
                                listPayrollTableItem.Add(tableItem);
                            }
                        }
                    }
                }

                #endregion

                asynTask = repoSys_AsynTask.FindBy(m => m.ID == Sys_AsynTaskID).FirstOrDefault();
                asynTask.PercentComplete += ((double)ProfileID.Count / (double)totalProfile);
                asynTask.Description = FileLog.GetFullPath(FileLog.FileName).Replace(".XML", "_" + DateTime.Now.ToString("yyyyMMdd") + ".XML");
                asynTask.TimeEnd = DateTime.Now;

                if (asynTask.PercentComplete >= 1)
                {
                    asynTask.Status = AsynTaskStatus.Done.ToString();
                    asynTask.PercentComplete = 1D;
                }

                //if (dataErrorCode == DataErrorCode.Locked)
                //{
                //    asynTask.PercentComplete = 1D;
                //    asynTask.Description = "Dữ Liệu Tính Lương Đã Bị Khóa";
                //    FileLog.WriteLog("Dữ liệu tính lương bị khóa", "--------------------", "--------------------");
                //}

                DatetimeStart = DateTime.Now;

                var connection = context.Database.Connection.GetAdoConnection();

                using (DbCommander commander = new DbCommander(connection))
                {
                    if (connection.IsSqlConnection())
                    {
                        var bulkCopyHelper = new SqlBulkCopyHelper(connection.ConnectionString);
                        var dtPayrollTable = commander.GetSchema("Columns", new string[] { null, null, typeof(Sal_PayrollTable).Name });
                        var dtPayrollTableItem = commander.GetSchema("Columns", new string[] { null, null, typeof(Sal_PayrollTableItem).Name });
                        var payrollTableFields = dtPayrollTable.Rows.OfType<System.Data.DataRow>().Select(d => d["Column_Name"].GetString()).ToArray();
                        var payrollTableItemFields = dtPayrollTableItem.Rows.OfType<System.Data.DataRow>().Select(d => d["Column_Name"].GetString()).ToArray();
                        bulkCopyHelper.WriteToServer(listPayrollTable, typeof(Sal_PayrollTable).Name, payrollTableFields);

                        foreach (var listPayrollTableItemBySize in listPayrollTableItem.Chunk(2000))
                        {
                            try
                            {
                                bulkCopyHelper.WriteToServer(listPayrollTableItemBySize.ToList(),
                                       typeof(Sal_PayrollTableItem).Name, payrollTableItemFields);
                            }
                            catch (Exception ex)
                            {
                                FileLog.WriteLog(ex.Message, "", "");
                            }
                        }
                    }
                    else
                    {
                        var dtPayrollTable = commander.GetSchema("Columns", new string[] { null, typeof(Sal_PayrollTable).Name });
                        var dtPayrollTableItem = commander.GetSchema("Columns", new string[] { null, typeof(Sal_PayrollTableItem).Name });
                        var payrollTableFields = dtPayrollTable.Rows.OfType<System.Data.DataRow>().Select(d => d["Name"].GetString()).ToArray();
                        var payrollTableItemFields = dtPayrollTableItem.Rows.OfType<System.Data.DataRow>().Select(d => d["Name"].GetString()).ToArray();

                        commander.InsertList(typeof(Sal_PayrollTable).Name, listPayrollTable, payrollTableFields);

                        foreach (var listPayrollTableItemBySize in listPayrollTableItem.Chunk(2000))
                        {
                            commander.InsertList(typeof(Sal_PayrollTableItem).Name, listPayrollTableItemBySize.ToList(), payrollTableItemFields);
                        }
                    }
                }
                FileLog.WriteLog("", "", "Save Change 100 Profile-" + Common.ComputeTime(DatetimeStart, DateTime.Now));

                //repoPayrollTableItem.Add(listPayrollTableItem);
                //repoPayrollTable.Add(listPayrollTable);
                unitOfWork.SaveChanges();
            }
        }
Beispiel #44
0
        /// <summary>
        /// Hàm lấy các phần tử là Enum
        /// </summary>
        /// <param name="TotalData">Class chứa tất cả các dữ liệu lấy lên để xử lý</param>
        /// <param name="listElementFormula">Lưu giá trị các thông thức đã tính rồi</param>
        /// <param name="profileItem">Nhân viên hiện tại được tính</param>
        /// <param name="CutOffDuration">Kỳ tính lương</param>
        /// <param name="formula">Công thức tính</param>
        /// <param name="listTmpDeduction">Biến tạm phục vụ cho tiền khấu trừ thâm niên của dự án SCV</param>
        /// <param name="DateClose">Ngày chốt lương</param>
        /// <returns></returns>
        public List<ElementFormula> GetStaticValues(ComputePayrollDataModel TotalData, List<ElementFormula> listElementFormula, Hre_ProfileEntity profileItem, Att_CutOffDurationEntity CutOffDuration, string ElementCode, Dictionary<Guid, ValueCount> listTmpDeduction)
        {
            Cat_ElementEntity formula = TotalData.listElement_All.Where(m => m.ElementCode == ElementCode).FirstOrDefault();
            ElementFormula item = new ElementFormula();

            #region Thêm các phần tử là loại phụ cấp
            if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUsualAllowance.Select(m => m.Code).ToArray()))
            {
                foreach (var t in TotalData.listUsualAllowance)
                {
                    listElementFormula.Add(new ElementFormula(t.Code, t.Formula, 0));
                }
            }
            #endregion

            #region Quy đổi tiền tệ
            if (CheckIsExistFormula(listElementFormula, formula, TotalData.listCurrency.Select(m => m.Code + "_BUYING").ToArray()))
            {
                //list lưu các element 
                var ListExChangeRateElement = TotalData.listElement_All.Where(m => m.ElementCode.EndsWith("_BUYING") && m.GradePayrollID == null).ToList();
                //list lưu giá trị tiền tệ
                var ListExChangeRateByGrade = TotalData.listExchangeRate.Where(m => m.MonthOfEffect >= CutOffDuration.DateStart && m.MonthOfEffect <= CutOffDuration.DateEnd).ToList();
                foreach (var i in ListExChangeRateElement)
                {
                    string[] arrCurrencyCode = i.ElementCode.Split('_').ToArray();
                    if (arrCurrencyCode.Count() != 3)
                    {
                        var ExChangeRateItem = ListExChangeRateByGrade.Where(m => m.CurrencyBaseCode == arrCurrencyCode[0] && m.CurrencyDestCode == arrCurrencyCode[1]).OrderByDescending(m => m.MonthOfEffect).FirstOrDefault();
                        if (ExChangeRateItem != null)
                        {
                            item = new ElementFormula(i.ElementCode, ExChangeRateItem.BuyingRate != null ? ExChangeRateItem.BuyingRate : 0, 0);
                            listElementFormula.Add(item);
                        }
                    }
                }
            }

            if (CheckIsExistFormula(listElementFormula, formula, TotalData.listCurrency.Select(m => m.Code + "_SELLING").ToArray()))
            {
                //list lưu các element 
                var ListExChangeRateElement = TotalData.listElement_All.Where(m => m.ElementCode.EndsWith("_SELLING") && m.GradePayrollID == null).ToList();
                //list lưu giá trị tiền tệ
                var ListExChangeRateByGrade = TotalData.listExchangeRate.Where(m => m.MonthOfEffect >= CutOffDuration.DateStart && m.MonthOfEffect <= CutOffDuration.DateEnd).ToList();
                foreach (var i in ListExChangeRateElement)
                {
                    string[] arrCurrencyCode = i.ElementCode.Split('_').ToArray();
                    if (arrCurrencyCode.Count() != 3)
                    {
                        var ExChangeRateItem = ListExChangeRateByGrade.Where(m => m.CurrencyBaseCode == arrCurrencyCode[0] && m.CurrencyDestCode == arrCurrencyCode[1]).OrderByDescending(m => m.MonthOfEffect).FirstOrDefault();
                        if (ExChangeRateItem != null)
                        {
                            item = new ElementFormula(i.ElementCode, ExChangeRateItem.SellingRate != null ? ExChangeRateItem.SellingRate : 0, 0);
                            listElementFormula.Add(item);
                        }
                    }
                }
            }
            #endregion

            #region Kiểm tra xem nhân viên này có phụ cấp phát sinh trong tháng đang tính lương hay không ?
            if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_T3").ToArray()))//đã lấy lên chưa ?
            {
                List<Sal_UnusualAllowanceEntity> listSal_UnusualT3 = new List<Sal_UnusualAllowanceEntity>();
                listSal_UnusualT3 = TotalData.listUnusualAllowanceT3.Where(m => m.ProfileID == profileItem.ID).ToList();
                ElementFormula _tmpitem = new ElementFormula();
                for (int j = 0; j < TotalData.listUnusualAllowanceCfg.Count; j++)
                {
                    //lay phu cap thang 3
                    _tmpitem = new ElementFormula();
                    _tmpitem.VariableName = TotalData.listUnusualAllowanceCfg[j].Code + "_T3";
                    var Sal_UnusualItem = listSal_UnusualT3.Where(m => m.UnusualEDTypeID == TotalData.listUnusualAllowanceCfg[j].ID && m.MonthStart <= CutOffDuration.DateEnd && (m.MonthEnd == null || m.MonthEnd >= CutOffDuration.DateStart)).ToList();
                    if (Sal_UnusualItem != null)
                    {
                        _tmpitem.Value = Sal_UnusualItem.Sum(m => m.Amount != null ? m.Amount : 0);
                        listElementFormula.Add(_tmpitem);
                    }
                    else
                    {
                        _tmpitem.Value = "0";
                        _tmpitem.ErrorMessage = "Không Có Phụ Cấp Trong Tháng 3";
                        listElementFormula.Add(_tmpitem);
                    }
                }
            }

            if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_DAYCLOSE_N_1").ToArray()))
            {
                DateTime Dateform = CutOffDuration.DateStart.AddMonths(-1);
                DateTime DateTo = CutOffDuration.DateEnd.AddMonths(-1);

                //Lấy các phần tử tính lương nằm trong Grade của nhân viên
                Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, Dateform, DateTo);
                //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương
                Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault();

                //ngày bắt đầu chốt lương
                DateTime DateClose = new DateTime(CutOffDuration.MonthYear.AddMonths(-1).Year, CutOffDuration.MonthYear.AddMonths(-1).Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1).AddDays(1).AddMonths(-1);
                //ngày kết thúc chốt lương
                DateTime DateEndClose = new DateTime(CutOffDuration.MonthYear.AddMonths(-1).Year, CutOffDuration.MonthYear.AddMonths(-1).Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1);

                List<Sal_UnusualAllowanceEntity> ListUnusualAllowanceByProfile = TotalData.listSalUnusualAllowance.Where(m => m.ProfileID == profileItem.ID && m.MonthStart != null && m.MonthStart <= DateEndClose && (m.MonthEnd == null || m.MonthEnd >= DateClose)).ToList();

                ElementFormula _item = new ElementFormula();
                foreach (var i in TotalData.listUnusualAllowanceCfg)
                {
                    var listValue = ListUnusualAllowanceByProfile.Where(m => m.UnusualEDTypeID == i.ID).OrderByDescending(m => m.MonthStart).FirstOrDefault();
                    if (listValue != null)
                    {
                        _item = new ElementFormula(i.Code + "_DAYCLOSE_N_1", listValue.Amount != null ? listValue.Amount : 0, 0);
                        listElementFormula.Add(_item);
                    }
                    else
                    {
                        _item = new ElementFormula(i.Code + "_DAYCLOSE_N_1", 0, 0);
                        listElementFormula.Add(_item);
                    }
                }
            }

            if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_DAYCLOSE").ToArray()))
            {
                //Lấy các phần tử tính lương nằm trong Grade của nhân viên
                Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd);
                //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương
                Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault();

                //ngày bắt đầu chốt lương
                DateTime DateClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1).AddDays(1).AddMonths(-1);
                //ngày kết thúc chốt lương
                DateTime DateEndClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1);

                List<Sal_UnusualAllowanceEntity> ListUnusualAllowanceByProfile = TotalData.listSalUnusualAllowance.Where(m => m.ProfileID == profileItem.ID && m.MonthStart != null && m.MonthStart <= DateEndClose && (m.MonthEnd == null || m.MonthEnd >= DateClose)).ToList();

                ElementFormula _item = new ElementFormula();
                foreach (var i in TotalData.listUnusualAllowanceCfg)
                {
                    var listValue = ListUnusualAllowanceByProfile.Where(m => m.UnusualEDTypeID == i.ID).OrderByDescending(m => m.MonthStart).FirstOrDefault();
                    if (listValue != null)
                    {
                        _item = new ElementFormula(i.Code + "_DAYCLOSE", listValue.Amount != null ? listValue.Amount : 0, 0);
                        listElementFormula.Add(_item);
                    }
                    else
                    {
                        _item = new ElementFormula(i.Code + "_DAYCLOSE", 0, 0);
                        listElementFormula.Add(_item);
                    }
                }
            }

            if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_AMOUNTOFOFFSET_N_1").ToArray()))
            {
                DateTime Dateform = CutOffDuration.DateStart.AddMonths(-1);
                DateTime DateTo = CutOffDuration.DateEnd.AddMonths(-1);

                //Lấy các phần tử tính lương nằm trong Grade của nhân viên
                Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, Dateform, DateTo);
                //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương
                Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault();

                //ngày bắt đầu chốt lương
                DateTime DateClose = new DateTime(CutOffDuration.MonthYear.AddMonths(-1).Year, CutOffDuration.MonthYear.AddMonths(-1).Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1).AddDays(1).AddMonths(-1);
                //ngày kết thúc chốt lương
                DateTime DateEndClose = new DateTime(CutOffDuration.MonthYear.AddMonths(-1).Year, CutOffDuration.MonthYear.AddMonths(-1).Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1);

                List<Sal_UnusualAllowanceEntity> listUnusualAllowanceByDateClose = TotalData.listSalUnusualAllowance.Where(m => m.MonthStart <= DateEndClose && (m.MonthEnd >= DateClose || m.MonthEnd == null) && m.ProfileID == profileItem.ID).ToList();

                ElementFormula _item = new ElementFormula();
                foreach (var i in TotalData.listUnusualAllowanceCfg)
                {
                    var listValue = listUnusualAllowanceByDateClose.Where(m => m.UnusualEDTypeID == i.ID).ToList();
                    if (listValue != null)
                    {
                        _item = new ElementFormula(i.Code + "_AMOUNTOFOFFSET_N_1", listValue.Sum(m => m.AmountOfOffSet != null ? m.AmountOfOffSet : 0), 0);
                        listElementFormula.Add(_item);
                    }
                    else
                    {
                        _item = new ElementFormula(i.Code + "_AMOUNTOFOFFSET_N_1", 0, 0);
                        listElementFormula.Add(_item);
                    }
                }

            }

            //lấy mức phụ cấp theo timeline tháng n-1
            if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_TIMELINE_N_1").ToArray()))
            {
                DateTime Dateform = CutOffDuration.DateStart.AddMonths(-1);
                DateTime DateTo = CutOffDuration.DateEnd.AddMonths(-1);

                //Lấy các phần tử tính lương nằm trong Grade của nhân viên
                Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, Dateform, DateTo);
                //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương
                Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault();

                //ngày bắt đầu chốt lương
                DateTime DateClose = new DateTime(CutOffDuration.MonthYear.AddMonths(-1).Year, CutOffDuration.MonthYear.AddMonths(-1).Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1).AddDays(1).AddMonths(-1);
                //ngày kết thúc chốt lương
                DateTime DateEndClose = new DateTime(CutOffDuration.MonthYear.AddMonths(-1).Year, CutOffDuration.MonthYear.AddMonths(-1).Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1);

                List<Cat_UnAllowCfgAmountEntity> listUnAllowCfgAmount = TotalData.listUnAllowCfgAmount.Where(m => m.FromDate <= DateEndClose && m.ToDate >= DateClose).ToList();

                ElementFormula _item = new ElementFormula();
                foreach (var i in TotalData.listUnusualAllowanceCfg)
                {
                    var listValue = listUnAllowCfgAmount.Where(m => m.UnusualAllowanceID != null && (Guid)m.UnusualAllowanceID == i.ID).ToList();
                    if (listValue != null)
                    {
                        _item = new ElementFormula(i.Code + "_TIMELINE_N_1", listValue.Sum(m => m.Amount != null ? m.Amount : 0), 0);
                        listElementFormula.Add(_item);
                    }
                    else
                    {
                        _item = new ElementFormula(i.Code + "_TIMELINE_N_1", 0, 0);
                        listElementFormula.Add(_item);
                    }
                }
            }

            //lấy mức phụ cấp theo timeline
            if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_TIMELINE").ToArray()))
            {
                //Lấy các phần tử tính lương nằm trong Grade của nhân viên
                Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd);
                //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương
                Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault();

                //ngày bắt đầu chốt lương
                DateTime DateClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1).AddDays(1).AddMonths(-1);
                //ngày kết thúc chốt lương
                DateTime DateEndClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1);

                List<Cat_UnAllowCfgAmountEntity> listUnAllowCfgAmount = TotalData.listUnAllowCfgAmount.Where(m => m.FromDate <= DateEndClose && m.ToDate >= DateClose).ToList();

                ElementFormula _item = new ElementFormula();
                foreach (var i in TotalData.listUnusualAllowanceCfg)
                {
                    var listValue = listUnAllowCfgAmount.Where(m => m.UnusualAllowanceID != null && (Guid)m.UnusualAllowanceID == i.ID).ToList();
                    if (listValue != null)
                    {
                        _item = new ElementFormula(i.Code + "_TIMELINE", listValue.Sum(m => m.Amount != null ? m.Amount : 0), 0);
                        listElementFormula.Add(_item);
                    }
                    else
                    {
                        _item = new ElementFormula(i.Code + "_TIMELINE", 0, 0);
                        listElementFormula.Add(_item);
                    }
                }
            }


            if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_N_1").ToArray()))//đã lấy lên chưa ?
            {
                List<Sal_UnusualAllowanceEntity> listSal_Unusual = new List<Sal_UnusualAllowanceEntity>();
                ElementFormula _tmpitem = new ElementFormula();
                listSal_Unusual = TotalData.listSalUnusualAllowance.Where(m => m.ProfileID == profileItem.ID).ToList();
                //lấy các loại phụ cấp của 6 tháng trước tháng tính lương (Honda)
                for (int j = 0; j < TotalData.listUnusualAllowanceCfg.Count; j++)
                {
                    for (int t = 1; t <= 6; t++)
                    {
                        _tmpitem = new ElementFormula();
                        _tmpitem.VariableName = TotalData.listUnusualAllowanceCfg[j].Code + "_N_" + t.ToString();
                        var Sal_UnusualItem = listSal_Unusual.Where(m => m.UnusualEDTypeID == TotalData.listUnusualAllowanceCfg[j].ID && m.MonthStart <= CutOffDuration.DateEnd.AddMonths(t * -1) && (m.MonthEnd == null || m.MonthEnd >= CutOffDuration.DateStart.AddMonths(t * -1))).ToList();
                        if (Sal_UnusualItem != null)
                        {
                            _tmpitem.Value = Sal_UnusualItem.Sum(m => m.Amount != null ? m.Amount : 0);
                            listElementFormula.Add(_tmpitem);
                        }
                        else
                        {
                            _tmpitem.Value = "0";
                            _tmpitem.ErrorMessage = "Không Có Phụ Cấp Trong Tháng";
                            listElementFormula.Add(_tmpitem);
                        }
                    }
                }
            }

            if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code).ToArray()))//đã lấy lên chưa ?
            {
                List<Sal_UnusualAllowanceEntity> listSal_Unusual = new List<Sal_UnusualAllowanceEntity>();
                // List<Sal_UnusualAllowanceEntity> listSal_UnusualT3 = new List<Sal_UnusualAllowanceEntity>();
                listSal_Unusual = TotalData.listSalUnusualAllowance.Where(m => m.ProfileID == profileItem.ID).ToList();
                // listSal_UnusualT3 = TotalData.listUnusualAllowanceT3.Where(m => m.ProfileID == profileItem.ID).ToList();
                //add loại phụ cấp bất thường vào list phần tử(listElement), các loại phụ cấp nào không có thì cho formula = 0
                for (int j = 0; j < TotalData.listUnusualAllowanceCfg.Count; j++)
                {
                    ElementFormula _tmpitem = new ElementFormula();
                    _tmpitem.VariableName = TotalData.listUnusualAllowanceCfg[j].Code;
                    var Sal_UnusualItem = listSal_Unusual.Where(m => m.UnusualEDTypeID == TotalData.listUnusualAllowanceCfg[j].ID && m.MonthStart <= CutOffDuration.DateEnd && (m.MonthEnd == null || m.MonthEnd >= CutOffDuration.DateStart)).ToList();
                    if (Sal_UnusualItem != null)
                    {
                        _tmpitem.Value = Sal_UnusualItem.Sum(m => m.Amount != null ? m.Amount : 0);
                        listElementFormula.Add(_tmpitem);
                    }
                    else
                    {
                        _tmpitem.Value = "0";
                        _tmpitem.ErrorMessage = "Không Có Phụ Cấp Trong Tháng";
                        listElementFormula.Add(_tmpitem);
                    }
                }
            }
            #endregion

            #region Lấy giá trị các phần tử là Enum

            var listAttendanceTableProCut = TotalData.listAttendanceTable.Where(m => m.ProfileID == profileItem.ID && m.DateStart <= CutOffDuration.DateEnd && m.DateEnd >= CutOffDuration.DateStart).FirstOrDefault();

            #region Enum HRE
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.HR_WORKINGDAY.ToString(), PayrollElement.HR_LEAVEDAY.ToString(), PayrollElement.HR_IS_LEAVEDAY.ToString(), PayrollElement.HR_IS_WORKINGDAY.ToString() }))
            {
                //Ngày vào làm
                item = new ElementFormula(PayrollElement.HR_WORKINGDAY.ToString(), profileItem.DateHire, 0);
                listElementFormula.Add(item);

                //Ngày nghỉ việc
                item = new ElementFormula(PayrollElement.HR_LEAVEDAY.ToString(), profileItem.DateQuit != null ? profileItem.DateQuit : DateTime.MinValue, 0, profileItem.DateQuit != null ? "" : "Null");
                listElementFormula.Add(item);

                //NV có ngày nghỉ việc trong tháng
                item = new ElementFormula(PayrollElement.HR_IS_LEAVEDAY.ToString(), (profileItem.DateQuit <= CutOffDuration.DateEnd && profileItem.DateQuit >= CutOffDuration.DateStart) == true ? 0 : 1, 0);
                listElementFormula.Add(item);

                //NV có ngày vào làm trong tháng
                item = new ElementFormula(PayrollElement.HR_IS_WORKINGDAY.ToString(), (profileItem.DateHire <= CutOffDuration.DateEnd && profileItem.DateHire >= CutOffDuration.DateStart) == true ? 1 : 0, 0);
                listElementFormula.Add(item);

            }

            ////Bậc / Hệ số lương (Code)
            //item = new ElementFormula(PayrollElement.HR_SALARYCLASSNAME.ToString(), profileItem.SalaryClassID != null ? profileItem.SalaryClassName : "", 0);
            //listElementFormula.Add(item);


            //Số ngày từ ngày vào đến cuối tháng, không tính những ngày dayoff từ ngày vào đến cuối tháng (VD: vào ngày 05/01, số ngày dayoff từ mùng 5 đến 31 = 6 => trả về: 31 (số ngày trong tháng) - 5 (ngày vào) + 1 (từ 5 đến 31 là 27 ngày nên phải + thêm 1) - 6 (số ngày dayoff từ ngày 05/01 đến 31/01) = 21)
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_COUNT_DAY_TO_DATEEND_CUTOFF.ToString()))
            {
                if (profileItem.DateHire != null && profileItem.DateHire >= new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, 1))
                {
                    DateTime DateStart = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, 1);
                    DateTime DateEnd = DateStart.AddMonths(1).AddDays(-1);
                    //số ngày trong tháng
                    double dayInCutoff = DateEnd.Subtract(profileItem.DateHire.Value).TotalDays + 1;
                    double dayOff = TotalData.listDayOff.Where(m => m.DateOff <= DateEnd && m.DateOff >= profileItem.DateHire.Value).Count();

                    item = new ElementFormula(PayrollElement.HR_COUNT_DAY_TO_DATEEND_CUTOFF.ToString(), dayInCutoff - dayOff, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.HR_COUNT_DAY_TO_DATEEND_CUTOFF.ToString(), 0, 0);
                    listElementFormula.Add(item);
                }
            }

            //Số ngày trong tháng tính lương - tổng số ngày dayoff trong tháng tính lương (VD: tháng 1 có 31 ngày - 8 ngày dayoff = 23)
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_COUNT_DAY_IN_CUTOFF.ToString()))
            {
                DateTime DateStart = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, 1);
                DateTime DateEnd = DateStart.AddMonths(1).AddDays(-1);

                double dayInCutoff = DateEnd.Subtract(DateStart).TotalDays + 1;
                double dayOff = TotalData.listDayOff.Where(m => m.DateOff <= DateEnd && m.DateOff >= DateStart).Count();

                item = new ElementFormula(PayrollElement.HR_COUNT_DAY_IN_CUTOFF.ToString(), dayInCutoff - dayOff, 0);
                listElementFormula.Add(item);
            }

            //Số ngày dayoff từ ngày 1 tháng tính lương đến ngày vào làm (VD: vào làm ngày 05/01, 01/01, 02/01 là ngày dayoff => trả về 2)
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_COUNT_DAYOFF_TO_DATEHIRE.ToString()))
            {
                //ngày đầu tháng tính lương
                DateTime DateStart = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, 1);
                //nếu ngày làm việc lớn hơn ngày đầu tháng
                if (profileItem.DateHire != null && profileItem.DateHire >= DateStart)
                {
                    int DayNumber = TotalData.listDayOff.Where(m => m.DateOff <= profileItem.DateHire.Value && m.DateOff >= DateStart).Count();
                    item = new ElementFormula(PayrollElement.HR_COUNT_DAYOFF_TO_DATEHIRE.ToString(), DayNumber, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.HR_COUNT_DAYOFF_TO_DATEHIRE.ToString(), 0, 0);
                    listElementFormula.Add(item);
                }
            }

            //Nhân viên có ngày vào làm hoặc ngày đi làm lại trong khoảng từ ngày 1 đến ngày chốt lương trong tháng tính lương thì trả về 1, nếu không trả về 0
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_IS_BACK_TO_WORK.ToString()))
            {
                //Lấy các phần tử tính lương nằm trong Grade của nhân viên
                Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd);
                //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương
                Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault();
                //kiểm tra ngày đi làm
                if (profileItem.DateHire != null && profileItem.DateHire.Value.Month == CutOffDuration.MonthYear.Month && profileItem.DateHire.Value.Year == CutOffDuration.MonthYear.Year)
                {
                    if (CatGrade.SalaryDayClose != null && profileItem.DateHire.Value.Day <= CatGrade.SalaryDayClose)
                    {
                        item = new ElementFormula(PayrollElement.HR_IS_BACK_TO_WORK.ToString(), 1, 0);
                        listElementFormula.Add(item);
                    }
                    else
                    {
                        item = new ElementFormula(PayrollElement.HR_IS_BACK_TO_WORK.ToString(), 0, 0);
                        listElementFormula.Add(item);
                    }
                }
                else//kiểm tra có ngày vào làm lại hay không
                {
                    if (CatGrade.SalaryDayClose != null)
                    {
                        List<Hre_WorkHistoryEntity> listWorkHistoryByProfile = TotalData.listWorkHistory.Where(m => m.ProfileID == profileItem.ID && m.DateComeBack != null && m.DateComeBack <= new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, (int)CatGrade.SalaryDayClose)).ToList();
                        if (listWorkHistoryByProfile.Count > 0)
                        {
                            item = new ElementFormula(PayrollElement.HR_IS_BACK_TO_WORK.ToString(), 1, 0);
                            listElementFormula.Add(item);
                        }
                        else
                        {
                            item = new ElementFormula(PayrollElement.HR_IS_BACK_TO_WORK.ToString(), 0, 0);
                            listElementFormula.Add(item);
                        }
                    }
                    else
                    {
                        item = new ElementFormula(PayrollElement.HR_IS_BACK_TO_WORK.ToString(), 0, 0);
                        listElementFormula.Add(item);
                    }
                }
            }

            //Nhân viên có trong  doanh sách kỷ luật trong tháng tính lương
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_NUMBER_DAY_BEFORE_WORK.ToString()))
            {
                double CountDay = 0;
                //nếu ngày vào làm lớn hơn
                if (profileItem.DateHire != null && profileItem.DateHire > CutOffDuration.DateStart && profileItem.DateHire <= CutOffDuration.DateEnd)
                {
                    DateTime dateStart = new DateTime(profileItem.DateHire.Value.Year, profileItem.DateHire.Value.Month, 1);
                    CountDay = profileItem.DateHire.Value.Subtract(dateStart).TotalDays;

                    int DayOff = TotalData.listDayOff.Where(m => ((m.OrgStructureID == null || m.OrgStructureID == profileItem.OrgStructureID) || m.OrgStructureID == profileItem.OrgStructureID) && m.DateOff >= dateStart && m.DateOff < profileItem.DateHire).Count();
                    CountDay -= DayOff;
                }

                //kiểm tra xem có vào làm lại hay không
                Hre_StopWorkingEntity StopWorkingByProfile = TotalData.listHre_StopWorking.Where(m => m.ProfileID != null && m.DateComeBack != null && m.ProfileID == profileItem.ID && m.DateComeBack >= CutOffDuration.DateStart && m.DateComeBack <= CutOffDuration.DateEnd).OrderByDescending(m => m.DateComeBack).FirstOrDefault();
                if (StopWorkingByProfile != null && StopWorkingByProfile.DateComeBack != null)
                {
                    DateTime dateStart = new DateTime(StopWorkingByProfile.DateComeBack.Value.Year, StopWorkingByProfile.DateComeBack.Value.Month, 1);
                    CountDay = StopWorkingByProfile.DateComeBack.Value.Subtract(dateStart).TotalDays;

                    int DayOff = TotalData.listDayOff.Where(m => (m.OrgStructureID == null || m.OrgStructureID == profileItem.OrgStructureID) && m.DateOff >= dateStart && m.DateOff < profileItem.DateHire).Count();
                    CountDay -= DayOff;
                }

                item = new ElementFormula(PayrollElement.HR_NUMBER_DAY_BEFORE_WORK.ToString(), CountDay, 0);
                listElementFormula.Add(item);
            }

            //Nhân viên có trong  doanh sách kỷ luật trong tháng tính lương
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_NUMBER_DAY_BEFORE_WORK_PREV.ToString()))
            {
                DateTime DateStartPrev = CutOffDuration.DateStart.AddMonths(-1);
                DateTime DateEndPrev = CutOffDuration.DateEnd.AddMonths(-1);
                double CountDay = 0;
                int DayClose = 1;

                //Lấy các phần tử tính lương nằm trong Grade của nhân viên
                Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd);
                Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault();
                if (CatGrade != null && CatGrade.SalaryDayClose != null)
                {
                    DayClose = (int)CatGrade.SalaryDayClose;
                }

                //nếu ngày vào làm lớn hơn
                if (profileItem.DateHire != null && profileItem.DateHire > DateStartPrev && profileItem.DateHire <= DateEndPrev && profileItem.DateHire.Value.Day > DayClose)
                {
                    CountDay = new DateTime(profileItem.DateHire.Value.Year, profileItem.DateHire.Value.Month, 1).AddMonths(1).AddDays(-1).Subtract(profileItem.DateHire.Value).TotalDays + 1;
                    DateStartPrev = new DateTime(profileItem.DateHire.Value.Year, profileItem.DateHire.Value.Month, 1).AddMonths(1).AddDays(-1);
                    int DayOff = TotalData.listDayOff.Where(m => (m.OrgStructureID == null || m.OrgStructureID == profileItem.OrgStructureID) && m.DateOff <= DateStartPrev && m.DateOff >= profileItem.DateHire).Count();
                    CountDay -= DayOff;
                }

                //kiểm tra xem có vào làm lại hay không
                Hre_StopWorkingEntity StopWorkingByProfile = TotalData.listHre_StopWorking.Where(m => m.ProfileID != null && m.DateComeBack != null && m.ProfileID == profileItem.ID && m.DateComeBack >= DateStartPrev && m.DateComeBack <= DateEndPrev).OrderByDescending(m => m.DateComeBack).FirstOrDefault();
                if (StopWorkingByProfile != null && StopWorkingByProfile.DateComeBack != null)
                {
                    CountDay = new DateTime(StopWorkingByProfile.DateComeBack.Value.Year, StopWorkingByProfile.DateComeBack.Value.Month, 1).AddMonths(1).AddDays(-1).Subtract(StopWorkingByProfile.DateComeBack.Value).TotalDays + 1;
                    DateStartPrev = new DateTime(profileItem.DateHire.Value.Year, profileItem.DateHire.Value.Month, 1).AddMonths(1).AddDays(-1);
                    int DayOff = TotalData.listDayOff.Where(m => (m.OrgStructureID == null || m.OrgStructureID == profileItem.OrgStructureID) && m.DateOff <= DateStartPrev && m.DateOff >= profileItem.DateHire).Count();
                    CountDay -= DayOff;
                }

                item = new ElementFormula(PayrollElement.HR_NUMBER_DAY_BEFORE_WORK_PREV.ToString(), CountDay, 0);
                listElementFormula.Add(item);
            }


            //Nhân viên có trong  doanh sách kỷ luật trong tháng tính lương
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_IS_DISCIPLINE.ToString()))//đã lấy lên chưa ?
            {
                DateTime datefrom = new DateTime(CutOffDuration.MonthYear.Year - 1, 4, 1);
                DateTime dateto = new DateTime(CutOffDuration.MonthYear.Year, 3, 31);
                var listDisciplineProfile = TotalData.listDiscipline.Where(m => m.ProfileID == profileItem.ID && m.DateOfEffective >= datefrom && m.DateOfEffective <= dateto).FirstOrDefault();

                item = new ElementFormula(PayrollElement.HR_IS_DISCIPLINE.ToString(), listDisciplineProfile != null ? 1 : 0, 0);
                listElementFormula.Add(item);
            }

            //Phần tử tổng thời gian tạm hoãn công việc tính tới cuối kỳ lương
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_TOTAL_DAY_STOP_WORKING.ToString()))//đã lấy lên chưa ?
            {
                item = new ElementFormula(PayrollElement.HR_TOTAL_DAY_STOP_WORKING.ToString(), SumStopWorkingDay(TotalData.listHre_StopWorking.Where(m => m.ProfileID == profileItem.ID).ToList(), CutOffDuration.DateEnd), 0);
                listElementFormula.Add(item);
            }

            //Nhân viên có được tính trợ cấp hay không (Có ngày vào làm từ 1996<=N<=31/12/2008)
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_IS_COMPUTE_SUBSIDIZE.ToString()))
            {
                DateTime from = new DateTime(1996, 1, 1);
                DateTime to = new DateTime(2008, 12, 31);
                item = new ElementFormula(PayrollElement.HR_IS_COMPUTE_SUBSIDIZE.ToString(), (profileItem.DateHire <= to && profileItem.DateHire >= from) == true ? 1 : 0, 0);
                listElementFormula.Add(item);
            }

            //Lấy thông tin hợp đồng
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_CONSTRACT_TYPE.ToString()))
            {
                //TotalData.
            }

            #region HDT JOB

            #region Ngày vào làm và ngày kết thúc HDT JOB tháng N
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_START_DATE_HDTJOB.ToString()) || CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_END_DATE_HDTJOB.ToString()))//đã lấy lên chưa ?
            {
                Hre_HDTJobEntity HDTJOB_DateFrom = new Hre_HDTJobEntity();
                //Ngày vào làm HDT JOB
                HDTJOB_DateFrom = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.DateFrom <= CutOffDuration.DateEnd && (m.DateTo >= CutOffDuration.DateStart || m.DateTo == null) && m.Status == HDTJobStatus.E_APPROVE.ToString()).OrderBy(m => m.DateFrom).FirstOrDefault();
                if (HDTJOB_DateFrom != null)
                {
                    DateTime form = HDTJOB_DateFrom.DateFrom != null ? (DateTime)HDTJOB_DateFrom.DateFrom : DateTime.MinValue;
                    DateTime to = HDTJOB_DateFrom.DateTo != null ? (DateTime)HDTJOB_DateFrom.DateTo : CutOffDuration.DateEnd;

                    item = new ElementFormula(PayrollElement.HR_START_DATE_HDTJOB.ToString(), form, 0);
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.HR_END_DATE_HDTJOB.ToString(), to, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.HR_START_DATE_HDTJOB.ToString(), DateTime.MinValue, 0, "Null");
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.HR_END_DATE_HDTJOB.ToString(), DateTime.MinValue, 0, "Null");
                    listElementFormula.Add(item);
                }
            }

            #endregion

            #region Ngày vào làm và ngày kết thúc HDT JOB tháng N-1
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.HR_END_DATE_HDTJOB_PREV.ToString(), PayrollElement.HR_START_DATE_HDTJOB_PREV.ToString() }))
            {
                var CutOffDuration_Prev = TotalData.listCutOffDuration.Where(m => m.MonthYear == CutOffDuration.MonthYear.AddMonths(-1)).OrderByDescending(m => m.MonthYear).FirstOrDefault();

                if (CutOffDuration_Prev != null)
                {
                    List<Hre_HDTJobEntity> listHre_HDTJob_Prev = new List<Hre_HDTJobEntity>();
                    Hre_HDTJobEntity HDTJOB_DateFrom = new Hre_HDTJobEntity();
                    //Ngày vào làm HDT JOB
                    HDTJOB_DateFrom = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.DateFrom <= CutOffDuration_Prev.DateEnd && (m.DateTo >= CutOffDuration_Prev.DateStart || m.DateTo == null) && m.Status == HDTJobStatus.E_APPROVE.ToString()).OrderBy(m => m.DateFrom).FirstOrDefault();
                    if (HDTJOB_DateFrom != null)
                    {
                        DateTime form = HDTJOB_DateFrom.DateFrom != null ? (DateTime)HDTJOB_DateFrom.DateFrom : DateTime.MinValue;
                        DateTime to = HDTJOB_DateFrom.DateTo != null ? (DateTime)HDTJOB_DateFrom.DateTo : CutOffDuration.DateEnd;

                        item = new ElementFormula(PayrollElement.HR_START_DATE_HDTJOB_PREV.ToString(), form, 0);
                        listElementFormula.Add(item);

                        item = new ElementFormula(PayrollElement.HR_END_DATE_HDTJOB_PREV.ToString(), to, 0);
                        listElementFormula.Add(item);
                    }
                    else
                    {
                        item = new ElementFormula(PayrollElement.HR_START_DATE_HDTJOB_PREV.ToString(), DateTime.MinValue, 0, "Null");
                        listElementFormula.Add(item);

                        item = new ElementFormula(PayrollElement.HR_END_DATE_HDTJOB_PREV.ToString(), DateTime.MinValue, 0, "Null");
                        listElementFormula.Add(item);
                    }
                }
                else
                {
                    item = new ElementFormula(PayrollElement.HR_START_DATE_HDTJOB_PREV.ToString(), DateTime.MinValue, 0, "Không tồn tại kỳ N-1");
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.HR_END_DATE_HDTJOB_PREV.ToString(), DateTime.MinValue, 0, "Không tồn tại kỳ N-1");
                    listElementFormula.Add(item);
                }

            }


            #endregion

            #region Tính số ngày công đi làm HDT JOB Tháng N

            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.ATT_WORKDAY_HDTJOB_4.ToString()) || CheckIsExistFormula(listElementFormula, formula, PayrollElement.ATT_WORKDAY_HDTJOB_5.ToString()))//đã lấy lên chưa ?
            {
                double HDTJobDay = 0;
                if (listAttendanceTableProCut != null)
                {
                    if (listAttendanceTableProCut.HDTJobType1 != null && listAttendanceTableProCut.HDTJobType1 == EnumDropDown.HDTJobType.E_TYPE4.ToString())
                    {
                        HDTJobDay += listAttendanceTableProCut.HDTJobDayCount1 != null ? (int)listAttendanceTableProCut.HDTJobDayCount1 : 0;
                    }
                    if (listAttendanceTableProCut.HDTJobType2 != null && listAttendanceTableProCut.HDTJobType2 == EnumDropDown.HDTJobType.E_TYPE4.ToString())
                    {
                        HDTJobDay += listAttendanceTableProCut.HDTJobDayCount2 != null ? (int)listAttendanceTableProCut.HDTJobDayCount2 : 0;
                    }
                    if (listAttendanceTableProCut.HDTJobType3 != null && listAttendanceTableProCut.HDTJobType3 == EnumDropDown.HDTJobType.E_TYPE4.ToString())
                    {
                        HDTJobDay += listAttendanceTableProCut.HDTJobDayCount3 != null ? (int)listAttendanceTableProCut.HDTJobDayCount3 : 0;
                    }
                }

                //Số ngày công làm HDT Job Loại 4 (tháng N)
                item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDTJOB_4.ToString(), HDTJobDay, 0);
                listElementFormula.Add(item);

                HDTJobDay = 0;
                if (listAttendanceTableProCut != null)
                {
                    if (listAttendanceTableProCut.HDTJobType1 != null && listAttendanceTableProCut.HDTJobType1 == EnumDropDown.HDTJobType.E_TYPE5.ToString())
                    {
                        HDTJobDay += listAttendanceTableProCut.HDTJobDayCount1 != null ? (int)listAttendanceTableProCut.HDTJobDayCount1 : 0;
                    }
                    if (listAttendanceTableProCut.HDTJobType2 != null && listAttendanceTableProCut.HDTJobType2 == EnumDropDown.HDTJobType.E_TYPE5.ToString())
                    {
                        HDTJobDay += listAttendanceTableProCut.HDTJobDayCount2 != null ? (int)listAttendanceTableProCut.HDTJobDayCount2 : 0;
                    }
                    if (listAttendanceTableProCut.HDTJobType3 != null && listAttendanceTableProCut.HDTJobType3 == EnumDropDown.HDTJobType.E_TYPE5.ToString())
                    {
                        HDTJobDay += listAttendanceTableProCut.HDTJobDayCount3 != null ? (int)listAttendanceTableProCut.HDTJobDayCount3 : 0;
                    }
                }

                //Số ngày công làm HDT Job Loại 5 (tháng N)
                item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDTJOB_5.ToString(), HDTJobDay, 0);
                listElementFormula.Add(item);
            }

            #endregion

            #region Tính số ngày công đi làm HDT JOB Tháng N-1

            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKDAY_HDTJOB_PREV_4.ToString(), PayrollElement.ATT_WORKDAY_HDTJOB_PREV_5.ToString() }))
            {
                //lấy dữ liệu công tháng N-1
                var listAttendanceTableProCut_Prev = TotalData.Att_AttendanceTable_Prev.Where(m => m.ProfileID == profileItem.ID).FirstOrDefault();

                double HDTJobDay = 0;
                if (listAttendanceTableProCut_Prev != null && listAttendanceTableProCut_Prev.HDTJobType1 != null && listAttendanceTableProCut_Prev.HDTJobType1 == EnumDropDown.HDTJobType.E_TYPE4.ToString())
                {
                    HDTJobDay += listAttendanceTableProCut_Prev.HDTJobDayCount1 != null ? (int)listAttendanceTableProCut_Prev.HDTJobDayCount1 : 0;
                }
                if (listAttendanceTableProCut_Prev != null && listAttendanceTableProCut_Prev.HDTJobType2 != null && listAttendanceTableProCut_Prev.HDTJobType2 == EnumDropDown.HDTJobType.E_TYPE4.ToString())
                {
                    HDTJobDay += listAttendanceTableProCut_Prev.HDTJobDayCount2 != null ? (int)listAttendanceTableProCut_Prev.HDTJobDayCount2 : 0;
                }
                if (listAttendanceTableProCut_Prev != null && listAttendanceTableProCut_Prev.HDTJobType3 != null && listAttendanceTableProCut_Prev.HDTJobType3 == EnumDropDown.HDTJobType.E_TYPE4.ToString())
                {
                    HDTJobDay += listAttendanceTableProCut_Prev.HDTJobDayCount3 != null ? (int)listAttendanceTableProCut_Prev.HDTJobDayCount3 : 0;
                }

                //Số ngày công làm HDT Job Loại 4 (tháng N)
                item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDTJOB_PREV_4.ToString(), HDTJobDay, 0);
                listElementFormula.Add(item);

                HDTJobDay = 0;
                if (listAttendanceTableProCut_Prev != null && listAttendanceTableProCut_Prev.HDTJobType1 != null && listAttendanceTableProCut_Prev.HDTJobType1 == EnumDropDown.HDTJobType.E_TYPE5.ToString())
                {
                    HDTJobDay += listAttendanceTableProCut_Prev.HDTJobDayCount1 != null ? (int)listAttendanceTableProCut_Prev.HDTJobDayCount1 : 0;
                }
                if (listAttendanceTableProCut_Prev != null && listAttendanceTableProCut_Prev.HDTJobType2 != null && listAttendanceTableProCut_Prev.HDTJobType2 == EnumDropDown.HDTJobType.E_TYPE5.ToString())
                {
                    HDTJobDay += listAttendanceTableProCut_Prev.HDTJobDayCount2 != null ? (int)listAttendanceTableProCut_Prev.HDTJobDayCount2 : 0;
                }
                if (listAttendanceTableProCut_Prev != null && listAttendanceTableProCut_Prev.HDTJobType3 != null && listAttendanceTableProCut_Prev.HDTJobType3 == EnumDropDown.HDTJobType.E_TYPE5.ToString())
                {
                    HDTJobDay += listAttendanceTableProCut_Prev.HDTJobDayCount3 != null ? (int)listAttendanceTableProCut_Prev.HDTJobDayCount3 : 0;
                }

                //Số ngày công làm HDT Job Loại 5 (tháng N)
                item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDTJOB_PREV_5.ToString(), HDTJobDay, 0);
                listElementFormula.Add(item);
            }

            #endregion

            #region Phần tử kiểm tra có ngày ra HDT hay không tháng N và tháng N-1

            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_HDT_IS_DATE_END.ToString(), PayrollElement.ATT_HDT_IS_DATE_END_N_1.ToString() }))
            {


                #region Tháng N
                List<Hre_HDTJobEntity> HDTJOBByProfile = new List<Hre_HDTJobEntity>();
                HDTJOBByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.DateFrom <= CutOffDuration.DateEnd && (m.DateTo >= CutOffDuration.DateStart || m.DateTo == null) && m.Status == HDTJobStatus.E_APPROVE.ToString()).ToList();
                if (HDTJOBByProfile.Any(m => m.DateTo == null))
                {
                    item = new ElementFormula(PayrollElement.ATT_HDT_IS_DATE_END.ToString(), 1, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.ATT_HDT_IS_DATE_END.ToString(), 0, 0);
                    listElementFormula.Add(item);
                }
                #endregion

                #region Tháng N-1

                DateTime DateStartN1 = CutOffDuration.DateStart.AddMonths(-1);
                DateTime DateEndN1 = CutOffDuration.DateEnd.AddMonths(-1);

                HDTJOBByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.DateFrom <= DateEndN1 && (m.DateTo >= DateStartN1 || m.DateTo == null) && m.Status == HDTJobStatus.E_APPROVE.ToString()).ToList();
                if (HDTJOBByProfile.Any(m => m.DateTo == null))
                {
                    item = new ElementFormula(PayrollElement.ATT_HDT_IS_DATE_END.ToString(), 1, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.ATT_HDT_IS_DATE_END.ToString(), 0, 0);
                    listElementFormula.Add(item);
                }
                #endregion


            }

            #endregion

            #region Số ngày làm HDT loại 4 và 5 trừ ngày DayOff (tháng N và tháng N-1)
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_4.ToString(), PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_5.ToString(), PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_4_N_1.ToString(), PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_5_N_1.ToString() }))
            {
                DateTime DateStartN1 = CutOffDuration.DateStart.AddMonths(-1);
                DateTime DateEndN1 = CutOffDuration.DateEnd.AddMonths(-1);

                List<Hre_HDTJobEntity> ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString()).ToList();
                List<Hre_HDTJobEntity> ListHDTByProfileN = ListHDTByProfile.Where(m => m.DateFrom <= CutOffDuration.DateEnd && (m.DateTo >= CutOffDuration.DateStart || m.DateTo == null)).ToList();
                List<Hre_HDTJobEntity> ListHDTByProfileN1 = ListHDTByProfile.Where(m => m.DateFrom <= DateEndN1 && (m.DateTo >= DateStartN1 || m.DateTo == null)).ToList();

                double ListDayOff = TotalData.listDayOff.Count(m => m.DateOff <= CutOffDuration.DateEnd && m.DateOff >= CutOffDuration.DateStart);
                double ListDayOffN1 = TotalData.listDayOff.Count(m => m.DateOff <= DateEndN1 && m.DateOff >= DateStartN1);

                #region tính số ngày làm HDT loại 4
                List<Hre_HDTJobEntity> ListHDTByProfileN_Type4 = ListHDTByProfileN.Where(m => m.Type == EnumDropDown.HDTJobType.E_TYPE4.ToString()).ToList();
                double Day_Type4 = 0;
                DateTime _tmp = new DateTime();
                foreach (var i in ListHDTByProfileN_Type4)
                {
                    _tmp = i.DateTo != null ? i.DateTo.Value : CutOffDuration.DateEnd;
                    if (i.DateFrom != null)
                    {
                        Day_Type4 += _tmp.Subtract(i.DateFrom.Value).TotalDays + 1;
                    }
                }
                item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_4.ToString(), Day_Type4, 0);
                listElementFormula.Add(item);
                #endregion

                #region tính số ngày làm HDT loại 5
                List<Hre_HDTJobEntity> ListHDTByProfileN_Type5 = ListHDTByProfileN.Where(m => m.Type == EnumDropDown.HDTJobType.E_TYPE5.ToString()).ToList();
                double Day_Type5 = 0;
                foreach (var i in ListHDTByProfileN_Type5)
                {
                    _tmp = i.DateTo != null ? i.DateTo.Value : CutOffDuration.DateEnd;
                    if (i.DateFrom != null)
                    {
                        Day_Type5 += _tmp.Subtract(i.DateFrom.Value).TotalDays + 1;
                    }
                }
                item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_5.ToString(), Day_Type5, 0);
                listElementFormula.Add(item);
                #endregion

                #region tính số ngày làm HDT loại 4 tháng N-1
                ListHDTByProfileN_Type4 = ListHDTByProfileN1.Where(m => m.Type == EnumDropDown.HDTJobType.E_TYPE4.ToString()).ToList();
                Day_Type4 = 0;
                _tmp = new DateTime();
                foreach (var i in ListHDTByProfileN_Type4)
                {
                    _tmp = i.DateTo != null ? i.DateTo.Value : CutOffDuration.DateEnd;
                    if (i.DateFrom != null)
                    {
                        Day_Type4 += _tmp.Subtract(i.DateFrom.Value).TotalDays + 1;
                    }
                }
                item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_4_N_1.ToString(), Day_Type4, 0);
                listElementFormula.Add(item);
                #endregion

                #region tính số ngày làm HDT loại 5 tháng N-1
                ListHDTByProfileN_Type5 = ListHDTByProfileN1.Where(m => m.Type == EnumDropDown.HDTJobType.E_TYPE5.ToString()).ToList();
                Day_Type5 = 0;
                foreach (var i in ListHDTByProfileN_Type5)
                {
                    _tmp = i.DateTo != null ? i.DateTo.Value : CutOffDuration.DateEnd;
                    if (i.DateFrom != null)
                    {
                        Day_Type5 += _tmp.Subtract(i.DateFrom.Value).TotalDays + 1;
                    }
                }
                item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_5_N_1.ToString(), Day_Type5, 0);
                listElementFormula.Add(item);
                #endregion

            }
            #endregion

            #region Số ngày Day Off từ đầu tháng đến ngày vào HDT

            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_DAYOFF_STARTMONTH_STARTHDT.ToString(), PayrollElement.ATT_DAYOFF_STARTMONTH_STARTHDT_N_1.ToString() }))
            {
                #region Tháng N
                Hre_HDTJobEntity ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= CutOffDuration.DateEnd && m.DateTo >= CutOffDuration.DateStart).OrderBy(m => m.DateFrom).FirstOrDefault();

                if (ListHDTByProfile != null)
                {
                    double DayOff = TotalData.listDayOff.Count(m => m.DateOff <= ListHDTByProfile.DateFrom && m.DateOff >= CutOffDuration.DateStart);
                    item = new ElementFormula(PayrollElement.ATT_DAYOFF_STARTMONTH_STARTHDT.ToString(), DayOff, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.ATT_DAYOFF_STARTMONTH_STARTHDT.ToString(), 0, 0, "null");
                    listElementFormula.Add(item);
                }
                #endregion

                #region Tháng N-1
                DateTime DateStartN1 = CutOffDuration.DateStart.AddMonths(-1);
                DateTime DateEndN1 = CutOffDuration.DateEnd.AddMonths(-1);
                ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= DateEndN1 && m.DateTo >= DateStartN1).OrderBy(m => m.DateFrom).FirstOrDefault();

                if (ListHDTByProfile != null)
                {
                    double DayOff = TotalData.listDayOff.Count(m => m.DateOff <= ListHDTByProfile.DateFrom && m.DateOff >= DateStartN1);
                    item = new ElementFormula(PayrollElement.ATT_DAYOFF_STARTMONTH_STARTHDT_N_1.ToString(), DayOff, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.ATT_DAYOFF_STARTMONTH_STARTHDT_N_1.ToString(), 0, 0, "null");
                    listElementFormula.Add(item);
                }
                #endregion
            }

            #endregion

            #region số ngày từ ngày vào hdt đến cuối tháng trừ số ngày dayoff từ ngày vào đến cuối tháng(tháng N và tháng N-1)

            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKDAY_STARTHDT_MONTHEND.ToString(), PayrollElement.ATT_WORKDAY_STARTHDT_MONTHEND_N_1.ToString() }))
            {
                double WorkDay = 0;
                double DayOff = 0;
                #region Tháng N
                List<Hre_HDTJobEntity> ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= CutOffDuration.DateEnd && m.DateTo >= CutOffDuration.DateStart).OrderBy(m => m.DateFrom).ToList();

                if (ListHDTByProfile.Count > 0)
                {
                    foreach (var i in ListHDTByProfile)
                    {
                        if (i.DateFrom != null && i.DateTo != null)
                        {
                            if (i.DateTo < CutOffDuration.DateEnd)
                            {
                                WorkDay += i.DateTo.Value.Subtract(i.DateFrom.Value).TotalDays + 1;
                            }
                            else
                            {
                                WorkDay += CutOffDuration.DateEnd.Subtract(i.DateFrom.Value).TotalDays + 1;
                            }
                        }
                    }
                    DayOff = TotalData.listDayOff.Count(m => m.DateOff >= ListHDTByProfile.FirstOrDefault().DateFrom && m.DateOff <= CutOffDuration.DateEnd);
                    item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_MONTHEND.ToString(), WorkDay - DayOff, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_MONTHEND.ToString(), 0, 0, "null");
                    listElementFormula.Add(item);
                }
                #endregion

                #region Tháng N-1
                DateTime DateStartN1 = CutOffDuration.DateStart.AddMonths(-1);
                DateTime DateEndN1 = CutOffDuration.DateEnd.AddMonths(-1);
                WorkDay = 0;
                DayOff = 0;
                ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= DateEndN1 && m.DateTo >= DateStartN1).OrderBy(m => m.DateFrom).ToList();

                if (ListHDTByProfile.Count > 0)
                {
                    foreach (var i in ListHDTByProfile)
                    {
                        if (i.DateFrom != null && i.DateTo != null)
                        {
                            if (i.DateTo < CutOffDuration.DateEnd)
                            {
                                WorkDay += i.DateTo.Value.Subtract(i.DateFrom.Value).TotalDays + 1;
                            }
                            else
                            {
                                WorkDay += CutOffDuration.DateEnd.Subtract(i.DateFrom.Value).TotalDays + 1;
                            }
                        }
                    }
                    DayOff = TotalData.listDayOff.Count(m => m.DateOff >= ListHDTByProfile.FirstOrDefault().DateFrom && m.DateOff <= CutOffDuration.DateEnd);
                    item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_MONTHEND_N_1.ToString(), WorkDay - DayOff, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_MONTHEND_N_1.ToString(), 0, 0, "null");
                    listElementFormula.Add(item);
                }

                #endregion
            }

            #endregion

            #region số ngày từ ngày vào hdt tháng N-1 đến ngày ra hdt tháng N-1 trừ ngày dayoff tháng N-1 và N-2
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_1.ToString(), PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_2.ToString() }))
            {
                DateTime DateStartN1 = CutOffDuration.DateStart.AddMonths(-1);
                DateTime DateEndN1 = CutOffDuration.DateEnd.AddMonths(-1);
                DateTime DateStartN2 = CutOffDuration.DateStart.AddMonths(-2);
                DateTime DateEndN2 = CutOffDuration.DateEnd.AddMonths(-2);
                double workDayHDT = 0;
                double DayOff = TotalData.listDayOff.Count(m => m.DateOff <= DateEndN1 && m.DateOff >= DateStartN1);

                #region Tháng N-1
                List<Hre_HDTJobEntity> ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= DateEndN1 && m.DateTo >= DateStartN1).OrderBy(m => m.DateFrom).ToList();
                foreach (var i in ListHDTByProfile)
                {
                    workDayHDT += i.DateTo.Value.Subtract(i.DateFrom.Value).TotalDays + 1;
                }
                item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_1.ToString(), workDayHDT - DayOff, 0);
                listElementFormula.Add(item);

                #endregion

                #region Tháng N-2
                workDayHDT = 0;
                DayOff = TotalData.listDayOff.Count(m => m.DateOff <= DateEndN2 && m.DateOff >= DateStartN2);
                ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= DateEndN2 && m.DateTo >= DateStartN2).OrderBy(m => m.DateFrom).ToList();
                foreach (var i in ListHDTByProfile)
                {
                    workDayHDT += i.DateTo.Value.Subtract(i.DateFrom.Value).TotalDays + 1;
                }
                item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_2.ToString(), workDayHDT - DayOff, 0);
                listElementFormula.Add(item);
                #endregion

            }
            #endregion

            #region Ngày vào HDT tháng N-1 và N-2

            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_STARTDATE_HDT_N_1.ToString(), PayrollElement.ATT_STARTDATE_HDT_N_2.ToString() }))
            {
                DateTime DateStartN1 = CutOffDuration.DateStart.AddMonths(-1);
                DateTime DateEndN1 = CutOffDuration.DateEnd.AddMonths(-1);
                DateTime DateStartN2 = CutOffDuration.DateStart.AddMonths(-2);
                DateTime DateEndN2 = CutOffDuration.DateEnd.AddMonths(-2);

                Hre_HDTJobEntity ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= DateEndN1 && m.DateTo >= DateStartN1).OrderBy(m => m.DateFrom).FirstOrDefault();
                if (ListHDTByProfile != null)
                {
                    item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_1.ToString(), ListHDTByProfile.DateFrom, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_1.ToString(), 0, 0);
                    listElementFormula.Add(item);
                }

                ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= DateEndN2 && m.DateTo >= DateStartN2).OrderBy(m => m.DateFrom).FirstOrDefault();
                if (ListHDTByProfile != null)
                {
                    item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_2.ToString(), ListHDTByProfile.DateFrom, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_2.ToString(), 0, 0);
                    listElementFormula.Add(item);
                }


            }

            #endregion

            #endregion

            #endregion

            #region Enum phần tử lương
            //Có tham gia công đoàn
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.IS_HRE_TRADEUNION.ToString()))
            {
                var ProfilePartyUnion = TotalData.listProfilePartyUnion.Where(m => m.ProfileID == profileItem.ID && m.IsTradeUnionist == true && m.TradeUnionistEnrolledDate != null && m.TradeUnionistEnrolledDate.Value <= CutOffDuration.DateEnd).FirstOrDefault();

                item = new ElementFormula(PayrollElement.IS_HRE_TRADEUNION.ToString(), ProfilePartyUnion != null ? 1 : 0, 0);
                listElementFormula.Add(item);
            }

            //Người phụ thuộc
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_DEPENDENT.ToString()))
            {
                item = new ElementFormula(PayrollElement.SAL_DEPENDENT.ToString(), GetDependantNumber(TotalData.listDependant, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd), 0);
                listElementFormula.Add(item);
            }

            //Mức lương HDT
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_SALARY_HDT.ToString(), PayrollElement.SAL_SALARY_HDT_N_1.ToString() }))
            {
                var Insurence = TotalData.listInsurance.Where(m => m.ProfileID == profileItem.ID && m.MonthYear != null && m.MonthYear.Value.Year == CutOffDuration.MonthYear.Year && m.MonthYear.Value.Month == CutOffDuration.MonthYear.Month).FirstOrDefault();
                item = new ElementFormula(PayrollElement.SAL_SALARY_HDT.ToString(), Insurence != null && Insurence.AmountChargeIns != null ? Insurence.AmountChargeIns : 0, 0);
                listElementFormula.Add(item);

                DateTime MonthYearPrev = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CutOffDuration.MonthYear.Day).AddMonths(-1);
                Insurence = TotalData.listInsurance.Where(m => m.ProfileID == profileItem.ID && m.MonthYear != null && m.MonthYear.Value.Year == MonthYearPrev.Year && m.MonthYear.Value.Month == MonthYearPrev.Month).FirstOrDefault();
                item = new ElementFormula(PayrollElement.SAL_SALARY_HDT_N_1.ToString(), Insurence != null && Insurence.AmountChargeIns != null ? Insurence.AmountChargeIns : 0, 0);
                listElementFormula.Add(item);
            }

            //Luong co ban thang 3
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_BASIC_SALARY_T3.ToString()))
            {
                item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_T3.ToString(), TotalData.listBasicSalaryT3.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).FirstOrDefault().GrossAmount, 0);
                listElementFormula.Add(item);
            }

            //Bậc lương
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_SALARY_RANK_NAME.ToString()))
            {
                Sal_BasicSalaryEntity BasicSalarybyProfile = new Sal_BasicSalaryEntity();
                BasicSalarybyProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).FirstOrDefault();
                item = new ElementFormula(PayrollElement.SAL_SALARY_RANK_NAME.ToString(), BasicSalarybyProfile != null ? BasicSalarybyProfile.SalaryRankName : "", 0);
                listElementFormula.Add(item);
            }

            //Bậc lương (class)
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_SALARY_CLASS_NAME.ToString()))
            {
                Sal_BasicSalaryEntity BasicSalarybyProfile = new Sal_BasicSalaryEntity();
                BasicSalarybyProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).FirstOrDefault();
                item = new ElementFormula(PayrollElement.SAL_SALARY_CLASS_NAME.ToString(), BasicSalarybyProfile != null ? BasicSalarybyProfile.SalaryClassName : "", 0);
                listElementFormula.Add(item);
            }

            //Hệ số lương nhân viên
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_BASIC_PERSONALRATE.ToString()))
            {
                List<Sal_BasicSalaryEntity> SalaryProfile = new List<Sal_BasicSalaryEntity>();
                SalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList();
                item = new ElementFormula(PayrollElement.SAL_BASIC_PERSONALRATE.ToString(), SalaryProfile.FirstOrDefault().PersonalRate != null ? SalaryProfile.FirstOrDefault().PersonalRate : 0, 0, "Null");
                listElementFormula.Add(item);
            }

            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_BASIC_SALARY_DATECLOSE.ToString(), PayrollElement.SAL_BASIC_SALARY_DATECLOSE_N_1.ToString() }))
            {
                List<Sal_BasicSalaryEntity> ListSalaryProfile = new List<Sal_BasicSalaryEntity>();
                ListSalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList();
                if (ListSalaryProfile.Count > 0)
                {
                    //Lấy các phần tử tính lương nằm trong Grade của nhân viên
                    Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd);
                    //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương
                    Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault();

                    //ngày bắt đầu chốt lương
                    DateTime DateClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1).AddDays(1).AddMonths(-1);
                    //ngày kết thúc chốt lương
                    DateTime DateEndClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1);

                    //lọc lại lương cơ bản theo kỳ chốt
                    ListSalaryProfile = ListSalaryProfile.Where(m => m.DateOfEffect <= DateEndClose).ToList();

                    //lương cơ bản gần nhất
                    Sal_BasicSalaryEntity SalaryProfile = ListSalaryProfile.FirstOrDefault();

                    //nếu ngày thay đổi lương nằm trong kỳ chốt lương thì lấy 2 mức
                    if (SalaryProfile.DateOfEffect >= DateClose && SalaryProfile.DateOfEffect <= DateEndClose)
                    {
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_DATECLOSE.ToString(), SalaryProfile.GrossAmount, 0);
                        listElementFormula.Add(item);

                        Sal_BasicSalaryEntity SalaryProfile_Prev = ListSalaryProfile.Where(m => m.DateOfEffect < DateClose).OrderByDescending(m => m.DateOfEffect).FirstOrDefault();
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_DATECLOSE_N_1.ToString(), SalaryProfile_Prev != null ? SalaryProfile_Prev.GrossAmount : "0", 0);
                        listElementFormula.Add(item);
                    }
                    else//chỉ áp dụng 1 mức lương
                    {
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_DATECLOSE.ToString(), SalaryProfile.GrossAmount, 0);
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_DATECLOSE_N_1.ToString(), SalaryProfile.GrossAmount, 0);
                        listElementFormula.Add(item);
                    }
                }
                else
                {
                    item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_DATECLOSE.ToString(), 0, 0, "Không có lương cơ bản !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_DATECLOSE_N_1.ToString(), 0, 0, "Không có thay đổi lương trong tháng !");
                    listElementFormula.Add(item);
                }
            }

            //Lương cơ bản
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_BASIC_SALARY.ToString(), PayrollElement.HR_SALARYCLASSNAME.ToString(), PayrollElement.SAL_BASIC_SALARY2.ToString(), PayrollElement.SAL_BASIC_SALARY1.ToString(), PayrollElement.SAL_BASIC_SALARY_N_1.ToString(), PayrollElement.SAL_BASIC_SALARY_N_2.ToString(), PayrollElement.SAL_BASIC_SALARY_N_3.ToString(), PayrollElement.SAL_BASIC_SALARY_N_4.ToString(), PayrollElement.SAL_BASIC_SALARY_N_5.ToString(), PayrollElement.SAL_BASIC_SALARY_N_6.ToString(), PayrollElement.SAL_INCENTIVE.ToString() }))
            {
                using (var context = new VnrHrmDataContext())
                {
                    var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                    List<Sal_BasicSalaryEntity> SalaryProfile = new List<Sal_BasicSalaryEntity>();
                    SalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList();
                    if (SalaryProfile != null && SalaryProfile.Count > 0)//có lương cơ bản
                    {
                        //bật lương
                        item = new ElementFormula(PayrollElement.HR_SALARYCLASSNAME.ToString(), SalaryProfile.FirstOrDefault().SalaryClassCode, 0, "Null");
                        listElementFormula.Add(item);

                        //lương cơ bản tháng hiện tại
                        if (SalaryProfile.FirstOrDefault().DateOfEffect <= CutOffDuration.DateStart)//chỉ có 1 mức lương trong tháng
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY.ToString(), SalaryProfile.OrderByDescending(m => m.DateOfEffect).FirstOrDefault().GrossAmount, 0);
                            listElementFormula.Add(item);
                            item = new ElementFormula(PayrollElement.SAL_INCENTIVE.ToString(), 0, 0);
                            listElementFormula.Add(item);
                        }
                        else//2 mức lương trong tháng
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY.ToString(), 0, 0, "Null");
                            listElementFormula.Add(item);

                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY2.ToString(), SalaryProfile.FirstOrDefault().GrossAmount, 0);
                            listElementFormula.Add(item);
                            if (SalaryProfile.Count > 1)
                            {
                                item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY1.ToString(), SalaryProfile[1].GrossAmount, 0);
                            }
                            else
                            {
                                item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY1.ToString(), 0, 0, "Null");
                            }

                            listElementFormula.Add(item);

                            #region Tính số ngày thay đổi lương
                            List<Att_RosterEntity> listRosterProfile = new List<Att_RosterEntity>();
                            //Lọc ra các roster thuộc nhân viên và nằm trong tháng tính lương
                            listRosterProfile = TotalData.listRoster.Where(m => m.ProfileID == profileItem.ID).ToList();

                            int totalLeave = 0;
                            foreach (var j in listRosterProfile)
                            {
                                DateTime _tmp = j.DateStart;
                                while (true)
                                {
                                    if (_tmp > CutOffDuration.DateEnd)
                                    {
                                        break;
                                    }
                                    if (_tmp >= SalaryProfile.FirstOrDefault().DateOfEffect)
                                    {
                                        int day = (int)_tmp.DayOfWeek;
                                        switch (day)
                                        {
                                            case 0://CN
                                                if (j.SunShiftID != null)
                                                {
                                                    totalLeave++;
                                                }
                                                break;
                                            case 1://T2
                                                if (j.MonShiftID != null)
                                                {
                                                    totalLeave++;
                                                }
                                                break;
                                            case 2:
                                                if (j.TueShiftID != null)
                                                {
                                                    totalLeave++;
                                                }
                                                break;
                                            case 3:
                                                if (j.WedShiftID != null)
                                                {
                                                    totalLeave++;
                                                }
                                                break;
                                            case 4:
                                                if (j.ThuShiftID != null)
                                                {
                                                    totalLeave++;
                                                }
                                                break;
                                            case 5:
                                                if (j.FriShiftID != null)
                                                {
                                                    totalLeave++;
                                                }
                                                break;
                                            case 6:
                                                if (j.SatShiftID != null)
                                                {
                                                    totalLeave++;
                                                }
                                                break;
                                            default:

                                                break;
                                        }
                                    }
                                    _tmp = _tmp.AddDays(1);
                                }
                            }
                            //cập nhật lại giá trị cho enum số ngày thay đổi lương
                            int days = (CutOffDuration.DateEnd - SalaryProfile.FirstOrDefault().DateOfEffect).Days;
                            days = days - totalLeave;
                            item = new ElementFormula(PayrollElement.SAL_INCENTIVE.ToString(), days, 0);
                            listElementFormula.Add(item);
                            //item = listElementFormula.Where(m => m.VariableName == PayrollElement.SAL_INCENTIVE.ToString()).FirstOrDefault();
                            //item.Value = days;
                            #endregion
                        }

                        #region lương cơ bản 6 tháng trước đó
                        var _basicsalaryPrevCurrentMonth = SalaryProfile.Where(m => m.DateOfEffect <= CutOffDuration.DateEnd.AddMonths(-1)).OrderByDescending(m => m.DateOfEffect).ToList();
                        if (_basicsalaryPrevCurrentMonth.Count > 0)
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_1.ToString(), _basicsalaryPrevCurrentMonth.FirstOrDefault().GrossAmount, 0);
                            listElementFormula.Add(item);
                        }
                        else
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_1.ToString(), 0, 0, "Null");
                            listElementFormula.Add(item);
                        }
                        _basicsalaryPrevCurrentMonth = SalaryProfile.Where(m => m.DateOfEffect <= CutOffDuration.DateEnd.AddMonths(-2)).OrderByDescending(m => m.DateOfEffect).ToList();
                        if (_basicsalaryPrevCurrentMonth.Count > 0)
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_2.ToString(), _basicsalaryPrevCurrentMonth.FirstOrDefault().GrossAmount, 0);
                            listElementFormula.Add(item);
                        }
                        else
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_2.ToString(), 0, 0, "Null");
                            listElementFormula.Add(item);
                        }
                        _basicsalaryPrevCurrentMonth = SalaryProfile.Where(m => m.DateOfEffect <= CutOffDuration.DateEnd.AddMonths(-3)).OrderByDescending(m => m.DateOfEffect).ToList();
                        if (_basicsalaryPrevCurrentMonth.Count > 0)
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_3.ToString(), _basicsalaryPrevCurrentMonth.FirstOrDefault().GrossAmount, 0);
                            listElementFormula.Add(item);
                        }
                        else
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_3.ToString(), 0, 0, "Null");
                            listElementFormula.Add(item);
                        }
                        _basicsalaryPrevCurrentMonth = SalaryProfile.Where(m => m.DateOfEffect <= CutOffDuration.DateEnd.AddMonths(-4)).OrderByDescending(m => m.DateOfEffect).ToList();
                        if (_basicsalaryPrevCurrentMonth.Count > 0)
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_4.ToString(), _basicsalaryPrevCurrentMonth.FirstOrDefault().GrossAmount, 0);
                            listElementFormula.Add(item);
                        }
                        else
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_4.ToString(), 0, 0, "Null");
                            listElementFormula.Add(item);
                        }
                        _basicsalaryPrevCurrentMonth = SalaryProfile.Where(m => m.DateOfEffect <= CutOffDuration.DateEnd.AddMonths(-5)).OrderByDescending(m => m.DateOfEffect).ToList();
                        if (_basicsalaryPrevCurrentMonth.Count > 0)
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_5.ToString(), _basicsalaryPrevCurrentMonth.FirstOrDefault().GrossAmount, 0);
                            listElementFormula.Add(item);
                        }
                        else
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_5.ToString(), 0, 0, "Null");
                            listElementFormula.Add(item);
                        }
                        _basicsalaryPrevCurrentMonth = SalaryProfile.Where(m => m.DateOfEffect <= CutOffDuration.DateEnd.AddMonths(-6)).OrderByDescending(m => m.DateOfEffect).ToList();
                        if (_basicsalaryPrevCurrentMonth.Count > 0)
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_6.ToString(), _basicsalaryPrevCurrentMonth.FirstOrDefault().GrossAmount, 0);
                            listElementFormula.Add(item);
                        }
                        else
                        {
                            item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_6.ToString(), 0, 0, "Null");
                            listElementFormula.Add(item);
                        }
                        #endregion
                    }
                    else//không có lương cơ bản
                    {
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY.ToString(), 0, 0, "Không có lương cơ bản tháng N");
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_1.ToString(), 0, 0, "Không có lương cơ bản tháng N-1");
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_2.ToString(), 0, 0, "Không có lương cơ bản tháng N-2");
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_3.ToString(), 0, 0, "Không có lương cơ bản tháng N-3");
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_4.ToString(), 0, 0, "Không có lương cơ bản tháng N-4");
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_5.ToString(), 0, 0, "Không có lương cơ bản tháng N-5");
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_6.ToString(), 0, 0, "Không có lương cơ bản tháng N-6");
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY1.ToString(), 0, 0, "Không có lương cơ bản tháng N");
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY2.ToString(), 0, 0, "Không có lương cơ bản tháng N");
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.SAL_INCENTIVE.ToString(), 0, 0, "Không có thay đổi lương tháng N");
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.HR_SALARYCLASSNAME.ToString(), 0, 0, "Không có Bậc / Hệ số lương tháng N");
                        listElementFormula.Add(item);
                    }
                }
            }

            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_UNUSUALALLOWANCE_MONTHSTART.ToString(), PayrollElement.SAL_UNUSUALALLOWANCE_MONTHEND.ToString(), PayrollElement.SAL_UNUSUALALLOWANCE_YEARSTART.ToString(), PayrollElement.SAL_UNUSUALALLOWANCE_YEAREND.ToString(), PayrollElement.SAL_UNUSUALALLOWANCE_NOCOMPENSATION.ToString() }))
            {
                Sal_UnusualAllowanceEntity SalUnusualAllowanceProfile = TotalData.listSalUnusualAllowance.Where(m => m.ProfileID == profileItem.ID && m.MonthStart <= CutOffDuration.DateEnd && (m.MonthEnd == null || m.MonthEnd >= CutOffDuration.DateStart)).FirstOrDefault();

                //Tháng bắt đầu hưởng PC
                item = new ElementFormula(PayrollElement.SAL_UNUSUALALLOWANCE_MONTHSTART.ToString(), SalUnusualAllowanceProfile != null ? SalUnusualAllowanceProfile.MonthStart != null ? SalUnusualAllowanceProfile.MonthStart : DateTime.MinValue : DateTime.MinValue, 0);
                listElementFormula.Add(item);

                //Tháng kết thúc hưởng PC
                item = new ElementFormula(PayrollElement.SAL_UNUSUALALLOWANCE_MONTHEND.ToString(), SalUnusualAllowanceProfile != null ? SalUnusualAllowanceProfile.MonthEnd != null ? SalUnusualAllowanceProfile.MonthEnd : DateTime.MinValue : DateTime.MinValue, 0);
                listElementFormula.Add(item);

                //Năm bắt đầu hưởng PC
                item = new ElementFormula(PayrollElement.SAL_UNUSUALALLOWANCE_YEARSTART.ToString(), SalUnusualAllowanceProfile != null ? SalUnusualAllowanceProfile.MonthStart != null ? SalUnusualAllowanceProfile.MonthStart.Value.Year : 0 : 0, 0);
                listElementFormula.Add(item);

                //Năm kết thúc hưởng PC
                item = new ElementFormula(PayrollElement.SAL_UNUSUALALLOWANCE_YEAREND.ToString(), SalUnusualAllowanceProfile != null ? SalUnusualAllowanceProfile.MonthEnd != null ? SalUnusualAllowanceProfile.MonthEnd.Value.Year : 0 : 0, 0);
                listElementFormula.Add(item);

                //Số tháng bù
                item = new ElementFormula(PayrollElement.SAL_UNUSUALALLOWANCE_NOCOMPENSATION.ToString(), SalUnusualAllowanceProfile != null ? SalUnusualAllowanceProfile.NoCompensation != null ? SalUnusualAllowanceProfile.NoCompensation : 0 : 0, 0);
                listElementFormula.Add(item);
            }

            //// Mức phụ cấp con nhỏ mỗi tháng
            //item = new ElementFormula(PayrollElement.SAL_UNUSUALALLOWANCE_NOCOMPENSATION.ToString(), 0, 0);
            //listElementFormula.Add(item);

            //Thánh tính lương
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.ATT_CUTOFFDURATION_MONTH.ToString()))
            {
                item = new ElementFormula(PayrollElement.ATT_CUTOFFDURATION_MONTH.ToString(), CutOffDuration.DateStart, 0);
                listElementFormula.Add(item);
            }

            //Tổng lương bộ phận của nhân viên
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_SALARY_DEPARTMENT.ToString()))
            {
                if (TotalData.listSal_SalaryDepartmentItem.Any(m => m.ProfileID == profileItem.ID))
                {
                    var AmountSalary = TotalData.listSal_SalaryDepartmentItem.Where(m => m.ProfileID == profileItem.ID).FirstOrDefault().AmoutSalary;
                    item = new ElementFormula(PayrollElement.SAL_SALARY_DEPARTMENT.ToString(), AmountSalary != null ? AmountSalary : 0, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.SAL_SALARY_DEPARTMENT.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                }
            }

            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_SALARY_DATE_CLOSE.ToString()))
            {
                Cat_GradePayrollEntity CatGradePayrollItem = TotalData.listCat_GradePayroll.Where(m => m.ID == FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd).ID).FirstOrDefault();
                if (CatGradePayrollItem != null && CatGradePayrollItem.SalaryDayClose != null)
                {
                    item = new ElementFormula(PayrollElement.SAL_SALARY_DATE_CLOSE.ToString(), CatGradePayrollItem.SalaryDayClose, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.SAL_SALARY_DATE_CLOSE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                }
            }

            //Giữ lương
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_HOLD_SALARY.ToString(), PayrollElement.SAL_HOLD_SALARY_AFTERTAX.ToString() }))
            {
                DateTime _tmpCutoffDuration = CutOffDuration.MonthYear.AddMonths(-1);
                Sal_HoldSalaryEntity holdSalaryItem = TotalData.listSal_HoldSalary.Where(m => m.ProfileID == profileItem.ID
                    && m.MonthEndSalary != null
                    && m.Status == EnumDropDown.WorkdayStatus.E_APPROVED.ToString()
                    && m.MonthEndSalary.Value.Month == _tmpCutoffDuration.Month
                    && m.MonthEndSalary.Value.Year == _tmpCutoffDuration.Year).FirstOrDefault();

                if (holdSalaryItem != null)
                {
                    item = new ElementFormula(PayrollElement.SAL_HOLD_SALARY.ToString(), holdSalaryItem.AmountSalary, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_HOLD_SALARY_AFTERTAX.ToString(), holdSalaryItem.AmountSalaryAfterTax, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.SAL_HOLD_SALARY.ToString(), 0, 0, "null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_HOLD_SALARY_AFTERTAX.ToString(), 0, 0, "null");
                    listElementFormula.Add(item);
                }
            }

            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_SALARY_ACCOUNT_NO.ToString(), PayrollElement.SAL_SALARY_GROUP_BANK.ToString(), PayrollElement.SAL_SALARY_BANK_NAME.ToString() }))
            {
                Sal_SalaryInformationEntity SalaryInfomationByProfile = TotalData.listSalaryInformation.FirstOrDefault(m => m.ProfileID == profileItem.ID);
                if (SalaryInfomationByProfile != null)
                {
                    item = new ElementFormula(PayrollElement.SAL_SALARY_ACCOUNT_NO.ToString(), SalaryInfomationByProfile.AccountNo, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_SALARY_GROUP_BANK.ToString(), SalaryInfomationByProfile.GroupBank, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_SALARY_BANK_NAME.ToString(), SalaryInfomationByProfile.BankName, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.SAL_SALARY_ACCOUNT_NO.ToString(), "", 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_SALARY_GROUP_BANK.ToString(), "", 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_SALARY_BANK_NAME.ToString(), "", 0, "Null");
                    listElementFormula.Add(item);
                }
            }

            #endregion

            #region Enum phần tử công

            #region Phần tử công tháng trước (N-1)
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKING_DAY_PREV.ToString(), PayrollElement.ATT_STD_DAY_PREV.ToString() }))
            {
                if (TotalData.Att_AttendanceTable_Prev != null)
                {
                    Att_AttendanceTableEntity _tmp = TotalData.Att_AttendanceTable_Prev.Where(m => m.ProfileID == profileItem.ID).FirstOrDefault();
                    if (_tmp != null)
                    {
                        item = new ElementFormula(PayrollElement.ATT_WORKING_DAY_PREV.ToString(), _tmp.RealWorkDayCount, 0);
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.ATT_STD_DAY_PREV.ToString(), _tmp.StdWorkDayCount, 0);
                        listElementFormula.Add(item);
                    }
                    else
                    {
                        item = new ElementFormula(PayrollElement.ATT_WORKING_DAY_PREV.ToString(), 0, 0, "Null");
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.ATT_STD_DAY_PREV.ToString(), 0, 0, "Null");
                        listElementFormula.Add(item);
                    }
                }
                else
                {
                    item = new ElementFormula(PayrollElement.ATT_WORKING_DAY_PREV.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.ATT_STD_DAY_PREV.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                }
            }
            #endregion

            #region Ngày công đi làm thực tế
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKING_DAY.ToString(), PayrollElement.ATT_WORKING_DAY_AFTER.ToString() }))
            {
                using (var context = new VnrHrmDataContext())
                {
                    var unitOfWork = (IUnitOfWork)new UnitOfWork(context);

                    //lấy lương cơ bản của nhân viên
                    List<Sal_BasicSalaryEntity> SalaryProfile = new List<Sal_BasicSalaryEntity>();
                    SalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList();

                    if (SalaryProfile.Count > 0 && SalaryProfile.FirstOrDefault().DateOfEffect > CutOffDuration.DateStart)//có thay đổi lương trong tháng
                    {
                        //ngày bắt đầu mức lương 1 và ngày bắt đầu mức lương 2
                        DateTime dateStart1 = CutOffDuration.DateStart;
                        DateTime dateStart2 = SalaryProfile.FirstOrDefault().DateOfEffect;

                        //lấy dữ liệu công theo cutoff
                        List<Att_AttendanceTableItemEntity> listAttTableItem = TotalData.listAttendanceTableItem.Where(m => m.ProfileID == profileItem.ID).ToList();

                        item = new ElementFormula(PayrollElement.ATT_WORKING_DAY.ToString(), listAttTableItem.Where(m => m.WorkDate < dateStart2).Count(), 0);
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.ATT_WORKING_DAY_AFTER.ToString(), listAttTableItem.Where(m => m.WorkDate >= dateStart2).Count(), 0);
                        listElementFormula.Add(item);
                    }
                    else
                    {
                        item = new ElementFormula(PayrollElement.ATT_WORKING_DAY.ToString(), listAttendanceTableProCut.RealWorkDayCount, 0);
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.ATT_WORKING_DAY_AFTER.ToString(), 0, 0);
                        listElementFormula.Add(item);
                    }
                }
            }
            #endregion

            #region Ngày công đi làm tính lương

            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKING_PAIDLEAVE_DAY.ToString(), PayrollElement.ATT_WORKING_PAIDLEAVE_DAY_AFTER.ToString() }))
            {
                using (var context = new VnrHrmDataContext())
                {
                    var unitOfWork = (IUnitOfWork)new UnitOfWork(context);


                    //lấy lương cơ bản của nhân viên
                    List<Sal_BasicSalaryEntity> SalaryProfile = new List<Sal_BasicSalaryEntity>();
                    SalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList();

                    if (SalaryProfile.Count > 0 && SalaryProfile.FirstOrDefault().DateOfEffect > CutOffDuration.DateStart)//có thay đổi lương trong tháng
                    {
                        //ngày bắt đầu mức lương 1 và ngày bắt đầu mức lương 2
                        DateTime dateStart1 = CutOffDuration.DateStart;
                        DateTime dateStart2 = SalaryProfile.FirstOrDefault().DateOfEffect;

                        //lưu số ngày công tính lương trước và sau khi thay đổi lương
                        double workpaid = 0;
                        double workpaid_after = 0;

                        //lấy dữ liệu công theo cutoff
                        List<Att_AttendanceTableItemEntity> listAttTableItem = TotalData.listAttendanceTableItem.Where(m => m.ProfileID == profileItem.ID).ToList();

                        //duyệt wa tất cả các dòng
                        foreach (var tableItem in listAttTableItem)
                        {
                            if (tableItem.WorkDate < dateStart2)//trước khi điều chỉnh
                            {
                                workpaid += tableItem.WorkPaidHours / tableItem.AvailableHours;
                            }
                            if (tableItem.WorkDate >= dateStart2)//sau khi điều chỉnh
                            {
                                workpaid_after += tableItem.WorkPaidHours / tableItem.AvailableHours;
                            }
                        }

                        item = new ElementFormula(PayrollElement.ATT_WORKING_PAIDLEAVE_DAY.ToString(), listAttTableItem.Where(m => m.WorkDate < dateStart2).Count(), 0);
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.ATT_WORKING_PAIDLEAVE_DAY_AFTER.ToString(), listAttTableItem.Where(m => m.WorkDate >= dateStart2).Count(), 0);
                        listElementFormula.Add(item);
                    }
                    else
                    {
                        item = new ElementFormula(PayrollElement.ATT_WORKING_PAIDLEAVE_DAY.ToString(), listAttendanceTableProCut.RealWorkDayCount, 0);
                        listElementFormula.Add(item);
                        item = new ElementFormula(PayrollElement.ATT_WORKING_PAIDLEAVE_DAY_AFTER.ToString(), 0, 0);
                        listElementFormula.Add(item);
                    }
                }
            }

            #endregion

            #region Số ngày phép năm cộng dồn - Số ngày phép ốm cộng dồn
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_ANNUAL_INCREMENTAL.ToString(), PayrollElement.ATT_SICK_INCREMENTAL.ToString() }))
            {
                List<Att_AnnualDetailEntity> AnnualDetailByProfile = TotalData.listAnnualDetail.Where(m => m.ProfileID == profileItem.ID).ToList();

                if (AnnualDetailByProfile != null && AnnualDetailByProfile.Count <= 0)
                {
                    var ANNUAL = AnnualDetailByProfile.FirstOrDefault(m => m.Type == AnnualLeaveDetailType.E_ANNUAL_LEAVE.ToString());
                    var SICK = AnnualDetailByProfile.FirstOrDefault(m => m.Type == AnnualLeaveDetailType.E_SICK_LEAVE.ToString());
                    item = new ElementFormula(PayrollElement.ATT_ANNUAL_INCREMENTAL.ToString(), ANNUAL != null ? ANNUAL.InitAvailable != null ? ANNUAL.InitAvailable : 0 : 0, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.ATT_SICK_INCREMENTAL.ToString(), SICK != null ? SICK.InitAvailable != null ? SICK.InitAvailable : 0 : 0, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.ATT_ANNUAL_INCREMENTAL.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.ATT_SICK_INCREMENTAL.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                }
            }

            #endregion

            //Phần tử công tháng hiện tại
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_STD_DAY.ToString(), PayrollElement.ATT_HOURS_PER_DAY.ToString(), PayrollElement.ATT_OVERTIME_PIT_HOURS.ToString(), PayrollElement.ATT_TOTAL_ANNUALLEAVE_AVAILABLE.ToString(), PayrollElement.ATT_ANNUALLEAVE_ADJACENT.ToString(), PayrollElement.ATT_TOTAL_SICK_AVAILABLE.ToString(), PayrollElement.ATT_SICK_ADJACENT.ToString(), PayrollElement.ATT_ANNUALLEAVE.ToString(), PayrollElement.ATT_SICKLEAVE.ToString(), PayrollElement.ATT_WORKING_NIGHTSHIFT.ToString() }))
            {
                if (listAttendanceTableProCut != null)
                {
                    //item = new ElementFormula(PayrollElement.ATT_WORKING_DAY.ToString(), listAttendanceTableProCut.RealWorkDayCount, 0);
                    //listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_STD_DAY.ToString(), listAttendanceTableProCut.StdWorkDayCount, 0);
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_HOURS_PER_DAY.ToString(), listAttendanceTableProCut.HourPerDay, 0);
                    listElementFormula.Add(item);

                    //item = new ElementFormula(PayrollElement.ATT_WORKING_PAIDLEAVE_DAY.ToString(), listAttendanceTableProCut.TotalPaidWorkDayCount, 0);
                    //listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_WORKING_NIGHTSHIFT.ToString(), listAttendanceTableProCut.NightShiftHours, 0);
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_TOTAL_ANNUALLEAVE_AVAILABLE.ToString(), listAttendanceTableProCut.TotalAnlDayAvailable != null ? listAttendanceTableProCut.TotalAnlDayAvailable : 0, 0);
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_ANNUALLEAVE_ADJACENT.ToString(), listAttendanceTableProCut.AnlDayAdjacent, 0);
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_ANNUALLEAVE.ToString(), listAttendanceTableProCut.AnlDayTaken, 0);
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_SICKLEAVE.ToString(), listAttendanceTableProCut.SickDayTaken, 0);
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_TOTAL_SICK_AVAILABLE.ToString(), listAttendanceTableProCut.TotalSickDayAvailable, 0);
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_SICK_ADJACENT.ToString(), listAttendanceTableProCut.SickDayAdjacent, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    //item = new ElementFormula(PayrollElement.ATT_WORKING_DAY.ToString(), 0, 0, "Null");
                    //listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_STD_DAY.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_HOURS_PER_DAY.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);

                    //item = new ElementFormula(PayrollElement.ATT_WORKING_PAIDLEAVE_DAY.ToString(), 0, 0, "Null");
                    //listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_WORKING_NIGHTSHIFT.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_TOTAL_ANNUALLEAVE_AVAILABLE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_ANNUALLEAVE_ADJACENT.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_TOTAL_SICK_AVAILABLE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_SICK_ADJACENT.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_SICKLEAVE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.ATT_ANNUALLEAVE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                }
            }


            //Số ngày nghỉ có trả lương
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_DAY.ToString(), PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_DAY_NOT_PAY.ToString() }))
            {
                using (var context = new VnrHrmDataContext())
                {
                    var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                    //Guid AttendanceTableItemByAttID = Guid.Empty;
                    double Total_LeaveDay = 0;
                    double Total_LeaveDay_NotPay = 0;
                    if (listAttendanceTableProCut != null)
                    {
                        // AttendanceTableItemByAtt = repoAttendanceTable.FindBy(m => m.IsDelete != true && m.ID == listAttendanceTableProCut.ID).FirstOrDefault();
                        //AttendanceTableItemByAttID = unitOfWork.CreateQueryable<Att_AttendanceTable>(m => m.ID == listAttendanceTableProCut.ID).Select(m => m.ID).FirstOrDefault();
                        //  var AttendanceTableItem = repoAttendanceTableItem.FindBy(m => m.IsDelete != true && m.AttendanceTableID == AttendanceTableItemByAttID).ToList();
                        var AttendanceTableItem = TotalData.listAttendanceTableItem.Where(m => m.AttendanceTableID == listAttendanceTableProCut.ID).ToList();

                        for (int j = 0; j < AttendanceTableItem.Count; j++)
                        {
                            if (AttendanceTableItem[j].LeaveTypeID != null)
                            {
                                var LeaveDay = TotalData.listLeavedayType.Where(m => m.ID == AttendanceTableItem[j].LeaveTypeID).FirstOrDefault();
                                if (LeaveDay != null)
                                {
                                    //code của là so sánh với IsWorkDay
                                    if (LeaveDay.IsAnnualLeave || LeaveDay.PaidRate >= 1)
                                    {
                                        Total_LeaveDay += AttendanceTableItem[j].PaidLeaveHours / AttendanceTableItem[j].AvailableHours;
                                    }
                                    else if (!LeaveDay.IsAnnualLeave && LeaveDay.PaidRate <= 0)
                                    {
                                        //Total_LeaveDay_NotPay += AttendanceTableItem[j].PaidLeaveHours / AttendanceTableItem[j].AvailableHours; 
                                        Total_LeaveDay_NotPay++;
                                    }
                                }
                            }
                        }
                    }
                    item = new ElementFormula(PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_DAY.ToString(), Total_LeaveDay, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_DAY_NOT_PAY.ToString(), Total_LeaveDay_NotPay, 0);
                    listElementFormula.Add(item);
                }
            }

            //Tổng số ngày công trong năm
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_TOTAL_WORKDAY_IN_YEAR.ToString() }))
            {
                var Attantendence = TotalData.listAttendanceTable.Where(m => m.ProfileID == profileItem.ID).ToList();
                item = new ElementFormula(PayrollElement.ATT_TOTAL_WORKDAY_IN_YEAR.ToString(), Attantendence.Sum(m => m.StdWorkDayCount), 0);
                listElementFormula.Add(item);
            }

            //Tổng số ngày công thực tế trong năm
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_TOTAL_REALITYWORKDAY_IN_YEAR.ToString() }))
            {
                var Attantendence = TotalData.listAttendanceTable.Where(m => m.ProfileID == profileItem.ID).ToList();
                item = new ElementFormula(PayrollElement.ATT_TOTAL_REALITYWORKDAY_IN_YEAR.ToString(), Attantendence.Sum(m => m.RealWorkDayCount), 0);
                listElementFormula.Add(item);
            }

            //Tổng số ngày làm việc trong năm (365-dayoff)
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_TOTAL_DAY_NOT_DAYOFF_IN_YEAR.ToString() }))
            {
                DateTime form = new DateTime(CutOffDuration.MonthYear.Year - 1, 4, 1);
                DateTime to = new DateTime(CutOffDuration.MonthYear.Year, 3, 31);
                int days = new DateTime(CutOffDuration.MonthYear.Year, 12, 31).DayOfYear;
                int dayOff = TotalData.listDayOff.Where(m => m.DateOff >= form && m.DateOff <= to && m.OrgStructureID == null).Count();
                item = new ElementFormula(PayrollElement.ATT_TOTAL_DAY_NOT_DAYOFF_IN_YEAR.ToString(), days - dayOff, 0);
                listElementFormula.Add(item);
            }


            #endregion

            #region Enum phần tử bảo hiểm
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.INS_HEALTH_INSURANCE.ToString(), PayrollElement.INS_SALARY_INSURANCE.ToString(), PayrollElement.INS_SOCIAL_INSURANCE.ToString(), PayrollElement.INS_UNEMP_INSURANCE.ToString(), PayrollElement.INS_SOCIAL_INSURANCE_PROFILE.ToString(), PayrollElement.INS_SOCIAL_INSURANCE_COMPANY.ToString(), PayrollElement.INS_UNEMP_INSURANCE_PROFILE.ToString(), PayrollElement.INS_UNEMP_INSURANCE_COMPANY.ToString(), PayrollElement.INS_HEALTH_INSURANCE_PROFILE.ToString(), PayrollElement.INS_HEALTH_INSURANCE_COMPANY.ToString() }))
            {
                Ins_ProfileInsuranceMonthlyEntity InsItem = TotalData.listInsurance.Where(m => m.ProfileID == profileItem.ID && m.MonthYear != null && m.MonthYear.Value.Year == CutOffDuration.MonthYear.Year && m.MonthYear.Value.Month == CutOffDuration.MonthYear.Month).FirstOrDefault();
                if (InsItem != null)
                {
                    item = new ElementFormula(PayrollElement.INS_HEALTH_INSURANCE.ToString(), InsItem.MoneyHealthInsurance == null ? null : InsItem.MoneyHealthInsurance, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_SALARY_INSURANCE.ToString(), InsItem.SalaryInsurance == null ? null : InsItem.SalaryInsurance, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_SOCIAL_INSURANCE.ToString(), InsItem.MoneySocialInsurance == null ? null : InsItem.MoneySocialInsurance, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_UNEMP_INSURANCE.ToString(), InsItem.MoneyUnEmpInsurance == null ? null : InsItem.MoneyUnEmpInsurance, 0);
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.INS_SOCIAL_INSURANCE_PROFILE.ToString(), InsItem.SocialInsEmpAmount == null ? null : InsItem.SocialInsEmpAmount, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_SOCIAL_INSURANCE_COMPANY.ToString(), InsItem.SocialInsComAmount == null ? null : InsItem.SocialInsComAmount, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_UNEMP_INSURANCE_PROFILE.ToString(), InsItem.UnemployEmpAmount == null ? null : InsItem.UnemployEmpAmount, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_UNEMP_INSURANCE_COMPANY.ToString(), InsItem.UnemployComAmount == null ? null : InsItem.UnemployComAmount, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_HEALTH_INSURANCE_PROFILE.ToString(), InsItem.HealthInsEmpAmount == null ? null : InsItem.HealthInsEmpAmount, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_HEALTH_INSURANCE_COMPANY.ToString(), InsItem.HealthInsComAmount == null ? null : InsItem.HealthInsComAmount, 0);
                    listElementFormula.Add(item);

                }
                else//nếu không có bảo hiểm thì cập nhất value = 0
                {
                    item = new ElementFormula(PayrollElement.INS_HEALTH_INSURANCE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_SALARY_INSURANCE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_SOCIAL_INSURANCE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_UNEMP_INSURANCE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.INS_SOCIAL_INSURANCE_PROFILE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_SOCIAL_INSURANCE_COMPANY.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_UNEMP_INSURANCE_PROFILE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_UNEMP_INSURANCE_COMPANY.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_HEALTH_INSURANCE_PROFILE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.INS_HEALTH_INSURANCE_COMPANY.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                }
            }

            #endregion

            #region Enum phần tử hoa hồng

            //Lấy taget & actual của shop
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_COM_TAGET_SHOP.ToString(), PayrollElement.SAL_COM_ACTUAL_SHOP.ToString(), PayrollElement.SAL_COM_PRECENT_REVENUE.ToString() }))
            {
                Sal_RevenueForShopEntity RevenueForShopItem = TotalData.listRevenueForShop.Where(m => m.ShopID == profileItem.ShopID && m.KPIBonusID == TotalData.listKPIBonus.Where(t => t.IsTotalRevenue == true).FirstOrDefault().ID && m.DateFrom <= CutOffDuration.DateEnd && m.DateTo >= CutOffDuration.DateStart).FirstOrDefault();
                if (RevenueForShopItem != null)
                {
                    item = new ElementFormula(PayrollElement.SAL_COM_TAGET_SHOP.ToString(), RevenueForShopItem.Target, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_COM_ACTUAL_SHOP.ToString(), RevenueForShopItem.Actual, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_COM_PRECENT_REVENUE.ToString(), RevenueForShopItem.Actual / RevenueForShopItem.Target, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.SAL_COM_TAGET_SHOP.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_COM_ACTUAL_SHOP.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_COM_PRECENT_REVENUE.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                }
            }


            //Lấy tên cửa hàng
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_COM_SHOPNAME.ToString()))
            {
                item = new ElementFormula(PayrollElement.SAL_COM_SHOPNAME.ToString(), profileItem.ShopName == null ? "" : profileItem.ShopName, 0);
                listElementFormula.Add(item);
            }


            //Lấy taget & actual của nhân viên
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_COM_TAGET_CUSTOMER.ToString(), PayrollElement.SAL_COM_ACTUAL_CUSTOMER.ToString() }))
            {
                Sal_RevenueForProfileEntity RevenueForProfileItem = new Sal_RevenueForProfileEntity();
                RevenueForProfileItem = TotalData.listRevenueForProfile.Where(m => m.ProfileID == profileItem.ID && m.DateFrom <= CutOffDuration.DateEnd && m.DateTo >= CutOffDuration.DateStart).FirstOrDefault();
                if (RevenueForProfileItem != null)
                {
                    item = new ElementFormula(PayrollElement.SAL_COM_TAGET_CUSTOMER.ToString(), RevenueForProfileItem.Target, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_COM_ACTUAL_CUSTOMER.ToString(), RevenueForProfileItem.Actual, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.SAL_COM_TAGET_CUSTOMER.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.SAL_COM_ACTUAL_CUSTOMER.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                }
            }


            //Số tháng làm việc
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_COM_WORKINGMONTH.ToString()))
            {
                double CountMonth = ((CutOffDuration.MonthYear.Year - profileItem.DateHire.Value.Year) * 12) + CutOffDuration.MonthYear.Month - profileItem.DateHire.Value.Month + (profileItem.DateHire.Value.Day < CutOffDuration.DateEnd.Day ? 1 : 0);
                item = new ElementFormula(PayrollElement.SAL_COM_WORKINGMONTH.ToString(), CountMonth, 0);
                listElementFormula.Add(item);
            }

            //tổng số nhân viên của cửa hàng
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_COM_COUNT_SHOPMEMBER.ToString()))
            {
                using (var context = new VnrHrmDataContext())
                {
                    var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                    var repoProfile = new CustomBaseRepository<Hre_Profile>(unitOfWork);
                    int TotalProfileForShop = repoProfile.FindBy(m => m.ShopID == profileItem.ShopID).Count();
                    item = new ElementFormula(PayrollElement.SAL_COM_COUNT_SHOPMEMBER.ToString(), TotalProfileForShop, 0);
                    listElementFormula.Add(item);
                }
            }

            //Chức danh
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_COM_JOBTITLE.ToString()))
            {
                item = new ElementFormula(PayrollElement.SAL_COM_JOBTITLE.ToString(), profileItem.PositionCode == null ? "" : profileItem.PositionCode, 0);
                listElementFormula.Add(item);
            }

            //Số lượng ca trưởng trong cửa hàng
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_COM_COUNT_SL.ToString(), PayrollElement.SAL_COM_RANK.ToString() }))
            {
                if (profileItem.ShopID != null)
                {
                    int Count_SL = (int)TotalData.listShop.Single(m => m.ID == profileItem.ShopID).NoShiftLeader;
                    item = new ElementFormula(PayrollElement.SAL_COM_COUNT_SL.ToString(), Count_SL, 0);
                    listElementFormula.Add(item);

                    //cấp bậc của cửa hàng
                    item = new ElementFormula(PayrollElement.SAL_COM_RANK.ToString(), TotalData.listShop.Single(m => m.ID == profileItem.ShopID).Rank, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.SAL_COM_COUNT_SL.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.SAL_COM_RANK.ToString(), 0, 0, "Null");
                    listElementFormula.Add(item);
                }
            }

            //Tổng doanh thu của tất cả nhân viên trong shop
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_TOTAL_ACTUAL_PROFILE_SHOP.ToString()))
            {
                using (var context = new VnrHrmDataContext())
                {
                    var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                    var repoProfile = new CustomBaseRepository<Hre_Profile>(unitOfWork);
                    var TotalPRofileInShop = repoProfile.FindBy(m => m.ShopID == profileItem.ShopID).ToList();
                    var RevenueForProfileInShop = TotalData.listRevenueForProfile.Where(m => TotalPRofileInShop.Any(t => t.ID == m.ProfileID) && m.DateFrom <= CutOffDuration.DateEnd && m.DateTo >= CutOffDuration.DateStart).ToList();
                    item = new ElementFormula(PayrollElement.SAL_TOTAL_ACTUAL_PROFILE_SHOP.ToString(), RevenueForProfileInShop.Sum(m => m.Actual), 0);
                    listElementFormula.Add(item);
                }

            }
            #endregion

            #region Enum phần tử đánh giá

            //Loại đánh giá
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.EVA_PERFORMANCE_TYPE_CODE.ToString(), PayrollElement.EVA_PERFORMANCE_LEVEL_NAME.ToString() }))
            {
                var PerformentceProfile = TotalData.listEva_Performance.Where(m => m.ProfileID == profileItem.ID && m.PeriodFromDate <= CutOffDuration.DateEnd && m.PeriodToDate >= CutOffDuration.DateStart).FirstOrDefault();

                item = new ElementFormula(PayrollElement.EVA_PERFORMANCE_TYPE_CODE.ToString(), PerformentceProfile != null ? PerformentceProfile.PerformanceTypeCode : "", 0);
                listElementFormula.Add(item);

                //Cấp độ đánh giá
                item = new ElementFormula(PayrollElement.EVA_PERFORMANCE_LEVEL_NAME.ToString(), PerformentceProfile != null ? PerformentceProfile.Level1Name : "", 0);
                listElementFormula.Add(item);
            }

            if (CheckIsExistFormula(listElementFormula, formula, CatElementType.Evaluation.ToString().ToUpper() + "_PERFORMANCETYPE_", TotalData.listPerformanceType.Select(m => m.Code).ToArray()))
            {
                DateTime YearStart = new DateTime(CutOffDuration.MonthYear.Year, 1, 1);
                DateTime YearEnd = new DateTime(CutOffDuration.MonthYear.Year, 12, 31);
                var PerformentceByProfile = TotalData.listEva_Performance.Where(m => m.ProfileID == profileItem.ID && m.DateEffect <= YearEnd && m.DateEffect >= YearStart).OrderByDescending(m => m.DateEffect).ToList();
                if (PerformentceByProfile != null)
                {
                    foreach (var i in TotalData.listPerformanceType)
                    {
                        var PerformentceByProfileAndType = PerformentceByProfile.FirstOrDefault(m => m.PerformanceTypeID == i.ID);
                        if (PerformentceByProfileAndType != null)
                        {
                            item = new ElementFormula(CatElementType.Evaluation.ToString().ToUpper() + "_PERFORMANCETYPE_" + i.Code, PerformentceByProfileAndType.Level1Name != null ? PerformentceByProfileAndType.Level1Name : "", 0);
                            listElementFormula.Add(item);
                        }
                        else
                        {
                            item = new ElementFormula(CatElementType.Evaluation.ToString().ToUpper() + "_PERFORMANCETYPE_" + i.Code, "", 0, "null");
                            listElementFormula.Add(item);
                        }
                    }
                }
                else
                {
                    foreach (var i in TotalData.listPerformanceType)
                    {
                        item = new ElementFormula(CatElementType.Evaluation.ToString().ToUpper() + "_PERFORMANCETYPE_" + i.Code, "", 0, "null");
                        listElementFormula.Add(item);
                    }
                }
            }

            #endregion

            #region Enum phần tử CanTeen

            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.CAN_SUMAMOUNT_N_1.ToString(), PayrollElement.CAN_AMOUNTEATNOTSTANDAR_N_1.ToString(), PayrollElement.CAN_AMOUNTCARDMORE_N_1.ToString(), PayrollElement.CAN_AMOUNTNOTWORKHASEAT_N_1.ToString(), PayrollElement.CAN_AMOUNTHDTJOB_N_1.ToString(), PayrollElement.CAN_AMOUNTNOTWORKBUTHASHDT_N_1.ToString(), PayrollElement.CAN_AMOUNTSUBTRACTWRONGSTANDARHDT_N_1.ToString() }))
            {
                DateTime DateStart = CutOffDuration.DateStart.AddMonths(-1);
                DateTime DateEnd = CutOffDuration.DateEnd.AddMonths(-1);

                var SumryMealRecordByRrofile = TotalData.listSumryMealRecord.Where(m => m.ProfileID == profileItem.ID && (m.DateFrom != null && m.DateTo != null) && m.DateFrom <= DateEnd && m.DateTo >= DateStart).OrderByDescending(m => m.DateFrom).FirstOrDefault();
                if (SumryMealRecordByRrofile != null)
                {
                    item = new ElementFormula(PayrollElement.CAN_SUMAMOUNT_N_1.ToString(), SumryMealRecordByRrofile.SumAmount != null ? SumryMealRecordByRrofile.SumAmount : 0, 0);
                    listElementFormula.Add(item);

                    item = new ElementFormula(PayrollElement.CAN_AMOUNTEATNOTSTANDAR_N_1.ToString(), SumryMealRecordByRrofile.AmountEatNotStandar != null ? SumryMealRecordByRrofile.AmountEatNotStandar : 0, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTCARDMORE_N_1.ToString(), SumryMealRecordByRrofile.SumAmountCardMore != null ? SumryMealRecordByRrofile.SumAmountCardMore : 0, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKHASEAT_N_1.ToString(), SumryMealRecordByRrofile.AmountNotWorkHasEat != null ? SumryMealRecordByRrofile.AmountNotWorkHasEat : 0, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTHDTJOB_N_1.ToString(), SumryMealRecordByRrofile.AmountHDTJob != null ? SumryMealRecordByRrofile.AmountHDTJob : 0, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKBUTHASHDT_N_1.ToString(), SumryMealRecordByRrofile.AmountNotWorkButHasHDT != null ? SumryMealRecordByRrofile.AmountNotWorkButHasHDT : 0, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTSUBTRACTWRONGSTANDARHDT_N_1.ToString(), SumryMealRecordByRrofile.AmountSubtractWorngStandarHDT != null ? SumryMealRecordByRrofile.AmountSubtractWorngStandarHDT : 0, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.CAN_SUMAMOUNT_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTEATNOTSTANDAR_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTCARDMORE_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKHASEAT_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTHDTJOB_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKBUTHASHDT_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTSUBTRACTWRONGSTANDARHDT_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                }

            }



            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.CAN_SUMAMOUNT.ToString(), PayrollElement.CAN_AMOUNTEATNOTSTANDAR.ToString(), PayrollElement.CAN_AMOUNTCARDMORE.ToString(), PayrollElement.CAN_AMOUNTNOTWORKHASEAT.ToString(), PayrollElement.CAN_AMOUNTHDTJOB.ToString(), PayrollElement.CAN_AMOUNTNOTWORKBUTHASHDT.ToString(), PayrollElement.CAN_AMOUNTSUBTRACTWRONGSTANDARHDT.ToString() }))
            {
                var SumryMealRecordByRrofile = TotalData.listSumryMealRecord.Where(m => m.ProfileID == profileItem.ID && (m.DateFrom != null && m.DateTo != null) && m.DateFrom <= CutOffDuration.DateEnd && m.DateTo >= CutOffDuration.DateStart).OrderByDescending(m => m.DateFrom).FirstOrDefault();
                if (SumryMealRecordByRrofile != null)
                {
                    item = new ElementFormula(PayrollElement.CAN_SUMAMOUNT.ToString(), SumryMealRecordByRrofile.SumAmount != null ? SumryMealRecordByRrofile.SumAmount : 0, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTEATNOTSTANDAR.ToString(), SumryMealRecordByRrofile.AmountEatNotStandar != null ? SumryMealRecordByRrofile.AmountEatNotStandar : 0, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTCARDMORE.ToString(), SumryMealRecordByRrofile.SumAmountCardMore != null ? SumryMealRecordByRrofile.SumAmountCardMore : 0, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKHASEAT.ToString(), SumryMealRecordByRrofile.AmountNotWorkHasEat != null ? SumryMealRecordByRrofile.AmountNotWorkHasEat : 0, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTHDTJOB.ToString(), SumryMealRecordByRrofile.AmountHDTJob != null ? SumryMealRecordByRrofile.AmountHDTJob : 0, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKBUTHASHDT.ToString(), SumryMealRecordByRrofile.AmountNotWorkButHasHDT != null ? SumryMealRecordByRrofile.AmountNotWorkButHasHDT : 0, 0);
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTSUBTRACTWRONGSTANDARHDT.ToString(), SumryMealRecordByRrofile.AmountSubtractWorngStandarHDT != null ? SumryMealRecordByRrofile.AmountSubtractWorngStandarHDT : 0, 0);
                    listElementFormula.Add(item);
                }
                else
                {
                    item = new ElementFormula(PayrollElement.CAN_SUMAMOUNT.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTEATNOTSTANDAR.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTCARDMORE.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKHASEAT.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTHDTJOB.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKBUTHASHDT.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                    item = new ElementFormula(PayrollElement.CAN_AMOUNTSUBTRACTWRONGSTANDARHDT.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !");
                    listElementFormula.Add(item);
                }

            }

            #endregion

            #endregion

            #region Các phần tử động
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.DYN_COUNTDAYOVERTIMEBYTYPE_.ToString(), new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }))
            {
                using (var context = new VnrHrmDataContext())
                {
                    var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                    //var repoAttendanceTable = new CustomBaseRepository<Att_AttendanceTable>(unitOfWork);
                    //var repoAttOvertime = new CustomBaseRepository<Att_Overtime>(unitOfWork);

                    //tách phần tử ra để lấy tham số
                    string Parameter = string.Empty;
                    var ttt = ParseFormulaToList(formula.Formula);
                    List<string> ListFormula = ParseFormulaToList(formula.Formula).Where(m => m.IndexOf('[') != -1 && m.IndexOf(']') != -1 && m.StartsWith("[" + PayrollElement.DYN_COUNTDAYOVERTIMEBYTYPE_.ToString())).ToList();

                    //Att_AttendanceTable listAttTable = TotalData.listAttendanceTable.Where(m => m.CutOffDurationID == CutOffDuration.ID && m.ProfileID == profileItem.ID && m.IsDelete != true).FirstOrDefault();
                    List<Att_AttendanceTableItemEntity> listAttTableItem = TotalData.listAttendanceTableItem.Where(m => m.AttendanceTableID == listAttendanceTableProCut.ID).ToList();

                    //lấy danh sách đăng ký tăng ca
                    List<Att_OvertimeEntity> listOverTime = TotalData.listOverTime.Where(m => m.ProfileID == profileItem.ID).ToList();

                    //duyệt qua các phần tử động để lấy tham số
                    foreach (var i in ListFormula)
                    {
                        string[] listParam = i.Split('_');
                        if (listParam.Count() >= 3)//nếu là 3 phần tử là đúng công thức, ngược lại là sai
                        {
                            string OtTypeCode = i.Replace(PayrollElement.DYN_COUNTDAYOVERTIMEBYTYPE_.ToString(), "").Replace("_" + listParam.LastOrDefault(), "").Replace("]", "").Replace("[", "");
                            double number = 0;
                            double CountOtDay = 0;
                            Cat_OvertimeTypeEntity OTType = TotalData.listOvertimeType.Where(m => m.Code == OtTypeCode).FirstOrDefault();

                            List<Att_OvertimeEntity> listOverTimeByTableItem = new List<Att_OvertimeEntity>();
                            Att_OvertimeEntity OverTimeItem = new Att_OvertimeEntity();
                            Cat_Shift ShiftItem = new Cat_Shift();

                            if (double.TryParse(listParam.LastOrDefault().Replace("]", "").Replace("[", ""), out number) && OTType != null)
                            {
                                number = number / 10;
                                CountOtDay = 0;
                                //lọc ra các loại OT theo loại
                                foreach (var tableItem in listAttTableItem)
                                {
                                    listOverTimeByTableItem = listOverTime.Where(m => m.WorkDate.Date == tableItem.WorkDate.Date).ToList();
                                    if (tableItem.OvertimeTypeID != null && tableItem.OvertimeTypeID == OTType.ID)
                                    {
                                        OverTimeItem = listOverTimeByTableItem.Where(m => m.OvertimeTypeID == (Guid)tableItem.OvertimeTypeID).FirstOrDefault();
                                        if (OverTimeItem != null && OverTimeItem.ShiftID != null)
                                        {
                                            ShiftItem = TotalData.listCat_Shift.Where(m => m.ID == (Guid)OverTimeItem.ShiftID).FirstOrDefault().Copy<Cat_Shift>();
                                            CountOtDay += tableItem.OvertimeHours / ShiftItem.udAvailableHours >= number ? 1 : 0;
                                        }
                                    }
                                    else if (tableItem.ExtraOvertimeTypeID != null && tableItem.ExtraOvertimeTypeID == OTType.ID)
                                    {
                                        OverTimeItem = listOverTimeByTableItem.Where(m => m.OvertimeTypeID == (Guid)tableItem.ExtraOvertimeTypeID).FirstOrDefault();
                                        if (OverTimeItem != null && OverTimeItem.ShiftID != null)
                                        {
                                            ShiftItem = TotalData.listCat_Shift.Where(m => m.ID == (Guid)OverTimeItem.ShiftID).FirstOrDefault().Copy<Cat_Shift>();
                                            CountOtDay += tableItem.ExtraOvertimeHours / ShiftItem.udAvailableHours >= number ? 1 : 0;
                                        }
                                    }
                                    else if (tableItem.ExtraOvertimeType2ID != null && tableItem.ExtraOvertimeType2ID == OTType.ID)
                                    {
                                        OverTimeItem = listOverTimeByTableItem.Where(m => m.OvertimeTypeID == (Guid)tableItem.ExtraOvertimeType2ID).FirstOrDefault();
                                        if (OverTimeItem != null && OverTimeItem.ShiftID != null)
                                        {
                                            ShiftItem = TotalData.listCat_Shift.Where(m => m.ID == (Guid)OverTimeItem.ShiftID).FirstOrDefault().Copy<Cat_Shift>();
                                            CountOtDay += tableItem.ExtraOvertimeHours2 / ShiftItem.udAvailableHours >= number ? 1 : 0;
                                        }
                                    }
                                    else if (tableItem.ExtraOvertimeType3ID != null && tableItem.ExtraOvertimeType3ID == OTType.ID)
                                    {
                                        OverTimeItem = listOverTimeByTableItem.Where(m => m.OvertimeTypeID == (Guid)tableItem.ExtraOvertimeType3ID).FirstOrDefault();
                                        if (OverTimeItem != null && OverTimeItem.ShiftID != null)
                                        {
                                            ShiftItem = TotalData.listCat_Shift.Where(m => m.ID == (Guid)OverTimeItem.ShiftID).FirstOrDefault().Copy<Cat_Shift>();
                                            CountOtDay += tableItem.ExtraOvertimeHours3 / ShiftItem.udAvailableHours >= number ? 1 : 0;
                                        }
                                    }
                                }
                                item = new ElementFormula(i.Replace("]", "").Replace("[", ""), CountOtDay, 0);
                                listElementFormula.Add(item);
                            }
                            else//sai công thức , không convert đc số giờ
                            {
                                item = new ElementFormula(i.Replace("]", "").Replace("[", ""), 0, 0, "Công thức động sai !");
                                listElementFormula.Add(item);
                            }
                        }
                        else
                        {
                            item = new ElementFormula(i.Replace("]", "").Replace("[", ""), 0, 0, "Công thức động sai !");
                            listElementFormula.Add(item);
                        }
                    }
                }
            }
            #endregion

            #region Lấy giá trị cho các phần tử là các loại OT và LeaveDay

            #region Lấy OT theo từng loại và lấy tổng số giờ tăng ca đã quy đổi ra hệ số 1

            #region OT tháng N


            List<Cat_ElementEntity> listElement_OT = new List<Cat_ElementEntity>();
            if (CheckIsExistFormula(listElementFormula, formula, "ATT_OVERTIME_", "_HOURS"))
            {
                using (var context = new VnrHrmDataContext())
                {
                    var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                    //var repoAttendanceTable = new CustomBaseRepository<Att_AttendanceTable>(unitOfWork);

                    //double SumOvertime = 0;
                    //double SumOvertimeInsurance = 0;

                    //lấy lương cơ bản của nhân viên
                    List<Sal_BasicSalaryEntity> SalaryProfile = new List<Sal_BasicSalaryEntity>();
                    SalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList();

                    //có thay đổi lương trong tháng
                    if (SalaryProfile.Count > 0 && SalaryProfile.FirstOrDefault().DateOfEffect > CutOffDuration.DateStart)//có thay đổi lương trong tháng
                    {
                        double OtHour = 0;
                        //ngày bắt đầu mức lương 1 và ngày bắt đầu mức lương 2
                        DateTime dateStart1 = CutOffDuration.DateStart;
                        DateTime dateStart2 = SalaryProfile.FirstOrDefault().DateOfEffect;

                        //lấy dữ liệu công theo cutoff
                        List<Att_AttendanceTableItemEntity> listAttTableItem = TotalData.listAttendanceTableItem.Where(m => m.ProfileID == profileItem.ID).ToList();

                        if (listAttTableItem != null && listAttTableItem.Count > 0)
                        {
                            listAttTableItem = listAttTableItem.Where(m => m.WorkDate < dateStart2).ToList();
                            //duyệt wa các loại ot
                            foreach (var OTType in TotalData.listOvertimeType)
                            {
                                OtHour = 0;
                                //tính số giờ OT của từng loại
                                foreach (var tableItem in listAttTableItem)
                                {
                                    if (tableItem.OvertimeTypeID != null && tableItem.OvertimeTypeID == OTType.ID)
                                    {
                                        OtHour += tableItem.OvertimeHours;
                                    }
                                    else if (tableItem.ExtraOvertimeTypeID != null && tableItem.ExtraOvertimeTypeID == OTType.ID)
                                    {
                                        OtHour += tableItem.ExtraOvertimeHours;
                                    }
                                    else if (tableItem.ExtraOvertimeType2ID != null && tableItem.ExtraOvertimeType2ID == OTType.ID)
                                    {
                                        OtHour += tableItem.ExtraOvertimeHours2;
                                    }
                                    else if (tableItem.ExtraOvertimeType3ID != null && tableItem.ExtraOvertimeType3ID == OTType.ID)
                                    {
                                        OtHour += tableItem.ExtraOvertimeHours3;
                                    }
                                }
                                item = new ElementFormula("ATT_OVERTIME_" + OTType.Code + "_HOURS", OtHour, 0);
                                listElementFormula.Add(item);
                            }
                        }
                        else
                        {
                            foreach (var OTType in TotalData.listOvertimeType)
                            {
                                item = new ElementFormula("ATT_OVERTIME_" + OTType.Code + "_HOURS", 0, 0);
                                listElementFormula.Add(item);
                            }
                        }
                    }
                    else//không thay đổi lương trong tháng
                    {
                        listElement_OT = TotalData.listElement_All.Where(m => m.ElementCode.StartsWith("ATT_OVERTIME_") && m.ElementCode.EndsWith("_HOURS")).ToList();
                        foreach (var OT in listElement_OT)
                        {
                            var itemOverTime = TotalData.listOvertimeType.Where(m => m.Code == OT.ElementCode.Replace("ATT_OVERTIME_", "").Replace("_HOURS", "")).FirstOrDefault();

                            double value = 0;
                            if (itemOverTime != null && listAttendanceTableProCut != null)
                            {
                                if (listAttendanceTableProCut.Overtime1Type != null && listAttendanceTableProCut.Overtime1Type == itemOverTime.ID)
                                {
                                    value += listAttendanceTableProCut.Overtime1Hours;
                                }
                                if (listAttendanceTableProCut.Overtime2Type != null && listAttendanceTableProCut.Overtime2Type == itemOverTime.ID)
                                {
                                    value += listAttendanceTableProCut.Overtime2Hours;
                                }
                                if (listAttendanceTableProCut.Overtime3Type != null && listAttendanceTableProCut.Overtime3Type == itemOverTime.ID)
                                {
                                    value += listAttendanceTableProCut.Overtime3Hours;
                                }
                                if (listAttendanceTableProCut.Overtime4Type != null && listAttendanceTableProCut.Overtime4Type == itemOverTime.ID)
                                {
                                    value += listAttendanceTableProCut.Overtime4Hours;
                                }
                                if (listAttendanceTableProCut.Overtime5Type != null && listAttendanceTableProCut.Overtime5Type == itemOverTime.ID)
                                {
                                    value += listAttendanceTableProCut.Overtime5Hours;
                                }
                                if (listAttendanceTableProCut.Overtime6Type != null && listAttendanceTableProCut.Overtime6Type == itemOverTime.ID)
                                {
                                    value += listAttendanceTableProCut.Overtime6Hours;
                                }
                            }
                            item = new ElementFormula(OT.ElementCode, value, 0);
                            listElementFormula.Add(item);

                            //if (itemOverTime != null)
                            //{
                            //    SumOvertimeInsurance += value * itemOverTime.TaxRate;//Tính số giờ tăng ca có chịu thuế
                            //    SumOvertime += value * itemOverTime.Rate;//tính hệ số và lưu vào biến tổng số giờ tăng ca
                            //}
                        }
                        ////Lưu giá trị cho Enum tổng số giớ tăng ca trong tháng
                        //item = new ElementFormula(PayrollElement.ATT_OVERTIME_HOURS.ToString(), SumOvertime, 0);
                        //listElementFormula.Add(item);

                        ////Lưu giá trị cho Enum tổng số giớ tăng ca trong tháng có tính thuế
                        //item = new ElementFormula(PayrollElement.ATT_OVERTIME_PIT_HOURS.ToString(), SumOvertimeInsurance, 0);
                        //listElementFormula.Add(item);
                    }
                }
            }
            #endregion

            #region Tổng giờ tăng ca trong tháng và tổng giờ tăng ca trong tháng có tính thuế

            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_OVERTIME_PIT_HOURS.ToString(), PayrollElement.ATT_OVERTIME_HOURS.ToString() }))
            {
                double SumOvertime = 0;
                double SumOvertimeInsurance = 0;

                foreach (var itemOverTime in TotalData.listOvertimeType)
                {
                    double value = 0;
                    if (itemOverTime != null && listAttendanceTableProCut != null)
                    {
                        if (listAttendanceTableProCut.Overtime1Type != null && listAttendanceTableProCut.Overtime1Type == itemOverTime.ID)
                        {
                            value += listAttendanceTableProCut.Overtime1Hours;
                        }
                        if (listAttendanceTableProCut.Overtime2Type != null && listAttendanceTableProCut.Overtime2Type == itemOverTime.ID)
                        {
                            value += listAttendanceTableProCut.Overtime2Hours;
                        }
                        if (listAttendanceTableProCut.Overtime3Type != null && listAttendanceTableProCut.Overtime3Type == itemOverTime.ID)
                        {
                            value += listAttendanceTableProCut.Overtime3Hours;
                        }
                        if (listAttendanceTableProCut.Overtime4Type != null && listAttendanceTableProCut.Overtime4Type == itemOverTime.ID)
                        {
                            value += listAttendanceTableProCut.Overtime4Hours;
                        }
                        if (listAttendanceTableProCut.Overtime5Type != null && listAttendanceTableProCut.Overtime5Type == itemOverTime.ID)
                        {
                            value += listAttendanceTableProCut.Overtime5Hours;
                        }
                        if (listAttendanceTableProCut.Overtime6Type != null && listAttendanceTableProCut.Overtime6Type == itemOverTime.ID)
                        {
                            value += listAttendanceTableProCut.Overtime6Hours;
                        }
                    }

                    if (itemOverTime != null)
                    {
                        SumOvertimeInsurance += value * itemOverTime.TaxRate;//Tính số giờ tăng ca có chịu thuế
                        SumOvertime += value * itemOverTime.Rate;//tính hệ số và lưu vào biến tổng số giờ tăng ca
                    }
                }
                //Lưu giá trị cho Enum tổng số giớ tăng ca trong tháng
                item = new ElementFormula(PayrollElement.ATT_OVERTIME_HOURS.ToString(), SumOvertime, 0);
                listElementFormula.Add(item);

                //Lưu giá trị cho Enum tổng số giớ tăng ca trong tháng có tính thuế
                item = new ElementFormula(PayrollElement.ATT_OVERTIME_PIT_HOURS.ToString(), SumOvertimeInsurance, 0);
                listElementFormula.Add(item);
            }

            #endregion

            #region Các loại OT nếu có thay đổi lương trong tháng

            if (CheckIsExistFormula(listElementFormula, formula, "ATT_OVERTIME_", "_HOURS_AFTER"))
            {
                using (var context = new VnrHrmDataContext())
                {
                    var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                    //var repoAttendanceTable = new CustomBaseRepository<Att_AttendanceTable>(unitOfWork);
                    //lấy lương cơ bản của nhân viên
                    List<Sal_BasicSalaryEntity> SalaryProfile = new List<Sal_BasicSalaryEntity>();
                    SalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList();

                    if (SalaryProfile.Count > 0 && SalaryProfile.FirstOrDefault().DateOfEffect > CutOffDuration.DateStart)//có thay đổi lương trong tháng
                    {
                        double OtHour = 0;
                        //ngày bắt đầu mức lương 1 và ngày bắt đầu mức lương 2
                        DateTime dateStart1 = CutOffDuration.DateStart;
                        DateTime dateStart2 = SalaryProfile.FirstOrDefault().DateOfEffect;

                        //lấy dữ liệu công theo cutoff
                        List<Att_AttendanceTableItemEntity> listAttTableItem = TotalData.listAttendanceTableItem.Where(m => m.ProfileID == profileItem.ID).ToList();

                        if (listAttTableItem != null && listAttTableItem.Count > 0)
                        {
                            listAttTableItem = listAttTableItem.Where(m => m.WorkDate >= dateStart2).ToList();
                            //duyệt wa các loại ot
                            foreach (var OTType in TotalData.listOvertimeType)
                            {
                                OtHour = 0;
                                //tính số giờ OT của từng loại
                                foreach (var tableItem in listAttTableItem)
                                {
                                    if (tableItem.OvertimeTypeID != null && tableItem.OvertimeTypeID == OTType.ID)
                                    {
                                        OtHour += tableItem.OvertimeHours;
                                    }
                                    else if (tableItem.ExtraOvertimeTypeID != null && tableItem.ExtraOvertimeTypeID == OTType.ID)
                                    {
                                        OtHour += tableItem.ExtraOvertimeHours;
                                    }
                                    else if (tableItem.ExtraOvertimeType2ID != null && tableItem.ExtraOvertimeType2ID == OTType.ID)
                                    {
                                        OtHour += tableItem.ExtraOvertimeHours2;
                                    }
                                    else if (tableItem.ExtraOvertimeType3ID != null && tableItem.ExtraOvertimeType3ID == OTType.ID)
                                    {
                                        OtHour += tableItem.ExtraOvertimeHours3;
                                    }
                                }
                                item = new ElementFormula("ATT_OVERTIME_" + OTType.Code + "_HOURS_AFTER", OtHour, 0);
                                listElementFormula.Add(item);
                            }
                        }
                        else
                        {
                            foreach (var OTType in TotalData.listOvertimeType)
                            {
                                item = new ElementFormula("ATT_OVERTIME_" + OTType.Code + "_HOURS_AFTER", 0, 0);
                                listElementFormula.Add(item);
                            }
                        }
                    }
                    else//không có lương cơ bản hoặc không có thay đổi lương trong tháng
                    {
                        foreach (var OTType in TotalData.listOvertimeType)
                        {
                            item = new ElementFormula("ATT_OVERTIME_" + OTType.Code + "_HOURS_AFTER", 0, 0);
                            listElementFormula.Add(item);
                        }
                    }
                }
            }

            #endregion

            #region OT tháng N-1
            if (CheckIsExistFormula(listElementFormula, formula, "ATT_OVERTIME_", "_HOURS_PREV"))
            {
                listElement_OT = TotalData.listElement_All.Where(m => m.ElementCode.StartsWith("ATT_OVERTIME_") && m.ElementCode.EndsWith("_HOURS_PREV")).ToList();
                if (listElement_OT != null && listElement_OT.Count > 0)
                {
                    foreach (var OT in listElement_OT)
                    {
                        var itemOverTime = TotalData.listOvertimeType.Where(m => m.Code == OT.ElementCode.Replace("ATT_OVERTIME_", "").Replace("_HOURS_PREV", "")).FirstOrDefault();

                        double value = 0;
                        var _tmpAttendanceTable = TotalData.Att_AttendanceTable_Prev.Where(m => m.ProfileID == profileItem.ID).FirstOrDefault();
                        if (itemOverTime != null && _tmpAttendanceTable != null)
                        {
                            if (_tmpAttendanceTable.Overtime1Type != null && _tmpAttendanceTable.Overtime1Type == itemOverTime.ID)
                            {
                                value += _tmpAttendanceTable.Overtime1Hours;
                            }
                            if (_tmpAttendanceTable.Overtime2Type != null && _tmpAttendanceTable.Overtime2Type == itemOverTime.ID)
                            {
                                value += _tmpAttendanceTable.Overtime2Hours;
                            }
                            if (_tmpAttendanceTable.Overtime3Type != null && _tmpAttendanceTable.Overtime3Type == itemOverTime.ID)
                            {
                                value += _tmpAttendanceTable.Overtime3Hours;
                            }
                            if (_tmpAttendanceTable.Overtime4Type != null && _tmpAttendanceTable.Overtime4Type == itemOverTime.ID)
                            {
                                value += _tmpAttendanceTable.Overtime4Hours;
                            }
                            if (_tmpAttendanceTable.Overtime5Type != null && _tmpAttendanceTable.Overtime5Type == itemOverTime.ID)
                            {
                                value += _tmpAttendanceTable.Overtime5Hours;
                            }
                            if (_tmpAttendanceTable.Overtime6Type != null && _tmpAttendanceTable.Overtime6Type == itemOverTime.ID)
                            {
                                value += _tmpAttendanceTable.Overtime6Hours;
                            }
                        }
                        item = new ElementFormula(OT.ElementCode, value, 0);
                        listElementFormula.Add(item);
                    }
                }
            }

            #endregion

            #endregion

            #region Lấy LeaveDay theo từng loại và lấy tổng nghỉ
            double SumLeaveday = 0;
            double SumLeavedayIsSalary = 0;

            //N-1
            double SumLeaveday_Prev = 0;
            double SumLeavedayIsSalary_Prev = 0;

            List<Cat_ElementEntity> listElement_Leave = new List<Cat_ElementEntity>();
            if (CheckIsExistFormula(listElementFormula, formula, "ATT_LEAVE_", "_HOURS") || CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_LEAVE_HOURS.ToString(), PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_HOURS.ToString() }))
            {
                listElement_Leave = TotalData.listElement_All.Where(m => m.ElementCode.StartsWith("ATT_LEAVE_") && m.ElementCode.EndsWith("_HOURS")).ToList();

                foreach (var LD in listElement_Leave)
                {
                    var itemLeaveday = TotalData.listLeavedayType.Where(m => m.Code == LD.ElementCode.Replace("ATT_LEAVE_", "").Replace("_HOURS", "")).FirstOrDefault();

                    double value = 0;
                    if (itemLeaveday != null && listAttendanceTableProCut != null)
                    {
                        if (listAttendanceTableProCut.LeaveDay1Type != null && listAttendanceTableProCut.LeaveDay1Type == itemLeaveday.ID)
                        {
                            value += listAttendanceTableProCut.LeaveDay1Hours;
                        }
                        if (listAttendanceTableProCut.LeaveDay2Type != null && listAttendanceTableProCut.LeaveDay2Type == itemLeaveday.ID)
                        {
                            value += listAttendanceTableProCut.LeaveDay2Hours;
                        }
                        if (listAttendanceTableProCut.LeaveDay3Type != null && listAttendanceTableProCut.LeaveDay3Type == itemLeaveday.ID)
                        {
                            value += listAttendanceTableProCut.LeaveDay3Hours;
                        }
                        if (listAttendanceTableProCut.LeaveDay4Type != null && listAttendanceTableProCut.LeaveDay4Type == itemLeaveday.ID)
                        {
                            value += listAttendanceTableProCut.LeaveDay4Hours;
                        }
                    }
                    item = new ElementFormula(LD.ElementCode, value, 0);
                    listElementFormula.Add(item);


                    SumLeaveday += value;//Tổng giờ nghỉ trong tháng
                    if (itemLeaveday != null)
                    {
                        SumLeavedayIsSalary += value * itemLeaveday.PaidRate;//tổng giờ nghỉ có trả lương
                    }

                    #region Lấy LeaveDay theo từng lại và lấy tổng ngày nghỉ tháng N - 1

                    value = 0;
                    var _tmpAttendanceTable = TotalData.Att_AttendanceTable_Prev.Where(m => m.ProfileID == profileItem.ID).FirstOrDefault();
                    if (itemLeaveday != null && _tmpAttendanceTable != null)
                    {
                        if (_tmpAttendanceTable.LeaveDay1Type != null && _tmpAttendanceTable.LeaveDay1Type == itemLeaveday.ID)
                        {
                            value += _tmpAttendanceTable.LeaveDay1Hours;
                        }
                        if (_tmpAttendanceTable.LeaveDay2Type != null && _tmpAttendanceTable.LeaveDay2Type == itemLeaveday.ID)
                        {
                            value += _tmpAttendanceTable.LeaveDay2Hours;
                        }
                        if (_tmpAttendanceTable.LeaveDay3Type != null && _tmpAttendanceTable.LeaveDay3Type == itemLeaveday.ID)
                        {
                            value += _tmpAttendanceTable.LeaveDay3Hours;
                        }
                        if (_tmpAttendanceTable.LeaveDay4Type != null && _tmpAttendanceTable.LeaveDay4Type == itemLeaveday.ID)
                        {
                            value += _tmpAttendanceTable.LeaveDay4Hours;
                        }
                    }
                    SumLeaveday_Prev += value;//Tổng giờ nghỉ trong tháng
                    if (itemLeaveday != null)
                    {
                        SumLeavedayIsSalary_Prev += value * itemLeaveday.PaidRate;//tổng giờ nghỉ có trả lương
                    }
                    #endregion
                }

                //tạo phần tử Enum tổng số giờ nghỉ trong tháng
                item = new ElementFormula(PayrollElement.ATT_LEAVE_HOURS.ToString(), SumLeaveday, 0);
                listElementFormula.Add(item);

                //tạo phần tử Enum tổng số giờ nghỉ trong tháng có tính lương
                item = new ElementFormula(PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_HOURS.ToString(), SumLeavedayIsSalary, 0);
                listElementFormula.Add(item);
            }

            //Số ngày nghỉ tháng N-1
            if (CheckIsExistFormula(listElementFormula, formula, "ATT_LEAVE_", "_DAY_PREV"))
            {
                listElement_Leave = TotalData.listElement_All.Where(m => m.ElementCode.StartsWith("ATT_LEAVE_") && m.ElementCode.EndsWith("_DAY_PREV")).ToList();
                var _tmpAttendanceTable = TotalData.Att_AttendanceTable_Prev.Where(m => m.ProfileID == profileItem.ID).FirstOrDefault();
                foreach (var LD in listElement_Leave)
                {
                    var itemLeaveday = TotalData.listLeavedayType.Where(m => m.Code == LD.ElementCode.Replace("ATT_LEAVE_", "").Replace("_DAY_PREV", "")).FirstOrDefault();

                    double value = 0;
                    if (itemLeaveday != null && _tmpAttendanceTable != null)
                    {
                        if (_tmpAttendanceTable.LeaveDay1Type != null && _tmpAttendanceTable.LeaveDay1Type == itemLeaveday.ID)
                        {
                            value += _tmpAttendanceTable.LeaveDay1Days != null ? (double)_tmpAttendanceTable.LeaveDay1Days : 0;
                        }
                        if (_tmpAttendanceTable.LeaveDay2Type != null && _tmpAttendanceTable.LeaveDay2Type == itemLeaveday.ID)
                        {
                            value += _tmpAttendanceTable.LeaveDay2Days != null ? (double)_tmpAttendanceTable.LeaveDay2Days : 0;
                        }
                        if (_tmpAttendanceTable.LeaveDay3Type != null && _tmpAttendanceTable.LeaveDay3Type == itemLeaveday.ID)
                        {
                            value += _tmpAttendanceTable.LeaveDay3Days != null ? (double)_tmpAttendanceTable.LeaveDay3Days : 0;
                        }
                        if (_tmpAttendanceTable.LeaveDay4Type != null && _tmpAttendanceTable.LeaveDay4Type == itemLeaveday.ID)
                        {
                            value += _tmpAttendanceTable.LeaveDay4Days != null ? (double)_tmpAttendanceTable.LeaveDay4Days : 0;
                        }
                    }
                    item = new ElementFormula(LD.ElementCode, value, 0);
                    listElementFormula.Add(item);
                }
            }

            //Tổng số Ngày Nghỉ từng loại trong năm
            if (CheckIsExistFormula(listElementFormula, formula, "ATT_LEAVE_", "_DAY_INYEAR"))
            {
                using (var context = new VnrHrmDataContext())
                {
                    string status = string.Empty;
                    var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                    var repoSys_AttendanceTable = new CustomBaseRepository<Att_AttendanceTable>(unitOfWork);
                    var repoSys_AttendanceTableItem = new CustomBaseRepository<Att_AttendanceTableItem>(unitOfWork);

                    DateTime from = new DateTime(CutOffDuration.MonthYear.Year - 1, 4, 1);
                    DateTime to = new DateTime(CutOffDuration.MonthYear.Year, 3, 31);

                    List<Att_AttendanceTable> listAttendanceTableByProfile = repoSys_AttendanceTable.FindBy(m => m.IsDelete != true && m.ProfileID == profileItem.ID && m.MonthYear != null && m.MonthYear.Value >= from && m.MonthYear.Value <= to).ToList();

                    listElement_Leave = TotalData.listElement_All.Where(m => m.ElementCode.StartsWith("ATT_LEAVE_") && m.ElementCode.EndsWith("_DAY_INYEAR")).ToList();

                    foreach (var LD in listElement_Leave)
                    {
                        var itemLeaveday = TotalData.listLeavedayType.Where(m => m.Code == LD.ElementCode.Replace("ATT_LEAVE_", "").Replace("_DAY_INYEAR", "")).FirstOrDefault();

                        double value = 0;
                        foreach (var _tmpAttendanceTable in listAttendanceTableByProfile)
                        {
                            if (itemLeaveday != null && _tmpAttendanceTable != null)
                            {
                                if (_tmpAttendanceTable.LeaveDay1Type != null && _tmpAttendanceTable.LeaveDay1Type == itemLeaveday.ID)
                                {
                                    value += _tmpAttendanceTable.LeaveDay1Days != null ? (double)_tmpAttendanceTable.LeaveDay1Days : 0;
                                }
                                if (_tmpAttendanceTable.LeaveDay2Type != null && _tmpAttendanceTable.LeaveDay2Type == itemLeaveday.ID)
                                {
                                    value += _tmpAttendanceTable.LeaveDay2Days != null ? (double)_tmpAttendanceTable.LeaveDay2Days : 0;
                                }
                                if (_tmpAttendanceTable.LeaveDay3Type != null && _tmpAttendanceTable.LeaveDay3Type == itemLeaveday.ID)
                                {
                                    value += _tmpAttendanceTable.LeaveDay3Days != null ? (double)_tmpAttendanceTable.LeaveDay3Days : 0;
                                }
                                if (_tmpAttendanceTable.LeaveDay4Type != null && _tmpAttendanceTable.LeaveDay4Type == itemLeaveday.ID)
                                {
                                    value += _tmpAttendanceTable.LeaveDay4Days != null ? (double)_tmpAttendanceTable.LeaveDay4Days : 0;
                                }
                            }
                        }
                        item = new ElementFormula(LD.ElementCode, value, 0);
                        listElementFormula.Add(item);
                    }
                }
            }


            #region N-1
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_LEAVE_HOURS_PREV.ToString(), PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_HOURS_PREV.ToString() }))
            {
                //Tổng số giờ nghỉ trong tháng N-1
                item = new ElementFormula(PayrollElement.ATT_LEAVE_HOURS_PREV.ToString(), SumLeaveday_Prev, 0);
                listElementFormula.Add(item);

                //Tổng số giờ nghỉ trong tháng có tính lương N-1
                item = new ElementFormula(PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_HOURS_PREV.ToString(), SumLeavedayIsSalary_Prev, 0);
                listElementFormula.Add(item);
            }
            #endregion
            #endregion

            #endregion

            #region  Honda - tổng số ngày làm việc theo từng ca của nhân viên trong tháng
            if (CheckIsExistFormula(listElementFormula, formula, "ATT_SHIFT_", "_HOURS"))
            {
                using (var context = new VnrHrmDataContext())
                {
                    string status = string.Empty;
                    var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                    //var repoAtt_AttendanceTableItem = new CustomBaseRepository<Att_AttendanceTableItem>(unitOfWork);

                    List<Att_AttendanceTableItemEntity> listAttTableItemByShift = new List<Att_AttendanceTableItemEntity>();
                    List<Att_AttendanceTableItemEntity> listAttendanceTableItemByAtt = TotalData.listAttendanceTableItem.Where(m => m.AttendanceTableID == listAttendanceTableProCut.ID).ToList();

                    for (int j = 0; j < TotalData.listCat_Shift.Count; j++)
                    {
                        listAttTableItemByShift = listAttendanceTableItemByAtt.Where(m => m.ShiftID != null && m.ShiftID == TotalData.listCat_Shift[j].ID).ToList();
                        item = new ElementFormula("ATT_SHIFT_" + TotalData.listCat_Shift[j].Code + "_HOURS", listAttTableItemByShift.Sum(m => m.AvailableHours), 0);
                        listElementFormula.Add(item);
                    }
                }
            }


            if (CheckIsExistFormula(listElementFormula, formula, "ATT_SHIFT_", "_DAY"))
            {
                using (var context = new VnrHrmDataContext())
                {
                    string status = string.Empty;
                    var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                    //var repoAtt_AttendanceTableItem = new CustomBaseRepository<Att_AttendanceTableItem>(unitOfWork);

                    List<Att_AttendanceTableItemEntity> listAttTableItemByShift = new List<Att_AttendanceTableItemEntity>();
                    List<Att_AttendanceTableItemEntity> listAttendanceTableItemByAtt = TotalData.listAttendanceTableItem.Where(m => m.AttendanceTableID == listAttendanceTableProCut.ID).ToList();
                    List<Att_AttendanceTableItemEntity> listAttendanceTableItemByAtt_Prev = new List<Att_AttendanceTableItemEntity>();
                    if (TotalData.Att_AttendanceTable_Prev.Count() >= 0)
                    {

                        Att_AttendanceTableEntity _tmp = TotalData.Att_AttendanceTable_Prev.Where(t => t.ProfileID == profileItem.ID).FirstOrDefault();
                        Guid _tmpID = Guid.Empty;
                        if (_tmp != null)
                        {
                            _tmpID = _tmp.ID;
                        }
                        listAttendanceTableItemByAtt_Prev = TotalData.listAttendanceTableItem.Where(m => m.AttendanceTableID == _tmpID).ToList();
                    }

                    for (int j = 0; j < TotalData.listCat_Shift.Count; j++)
                    {
                        listAttTableItemByShift = listAttendanceTableItemByAtt.Where(m => m.ShiftID != null && m.ShiftID == TotalData.listCat_Shift[j].ID).ToList();
                        if (listAttTableItemByShift != null && listAttTableItemByShift.Count > 0)
                        {
                            item = new ElementFormula("ATT_SHIFT" + "_" + TotalData.listCat_Shift[j].Code + "_" + "DAY", listAttTableItemByShift.Where(d => d.AvailableHours > 0).Sum(d => (d.WorkPaidHours + d.LateEarlyMinutes / 60.0) / d.AvailableHours), 0);
                            listElementFormula.Add(item);
                        }
                        else
                        {
                            item = new ElementFormula("ATT_SHIFT" + "_" + TotalData.listCat_Shift[j].Code + "_" + "DAY", 0, 0);
                            listElementFormula.Add(item);
                        }

                        //tháng N-1
                        listAttTableItemByShift = listAttendanceTableItemByAtt_Prev.Where(m => m.ShiftID != null && m.ShiftID == TotalData.listCat_Shift[j].ID).ToList();
                        if (listAttTableItemByShift != null && listAttTableItemByShift.Count > 0)
                        {
                            item = new ElementFormula("ATT_SHIFT" + "_" + TotalData.listCat_Shift[j].Code + "_" + "DAY_PREV", listAttTableItemByShift.Where(d => d.AvailableHours > 0).Sum(d => (d.WorkPaidHours + d.LateEarlyMinutes / 60.0) / d.AvailableHours), 0);
                            listElementFormula.Add(item);
                        }
                        else
                        {
                            item = new ElementFormula("ATT_SHIFT" + "_" + TotalData.listCat_Shift[j].Code + "_" + "DAY_PREV", 0, 0);
                            listElementFormula.Add(item);
                        }
                    }
                }

            }

            #endregion

            #region Lấy giá trị cho các loại phần tử là Hoa Hồng

            if (CheckIsExistFormula(listElementFormula, formula, CatElementType.Comission.ToString().ToUpper(), ""))
            {
                //lấy doanh thu của shop trong tháng
                List<Sal_RevenueRecordEntity> revenueShopInMonth = new List<Sal_RevenueRecordEntity>();
                if (profileItem.ShopID != null)
                {
                    revenueShopInMonth = TotalData.listRevenueRecord.Where(m => m.ShopID == profileItem.ShopID).ToList();
                }

                if (TotalData.listKPIBonus != null && TotalData.listKPIBonus.Count > 0)
                {
                    foreach (var j in TotalData.listKPIBonus)
                    {
                        if (revenueShopInMonth.Any(m => m.KPIBonusID == j.ID))
                        {
                            listElementFormula.Add(new ElementFormula(CatElementType.Comission.ToString().ToUpper() + "_" + j.Code, revenueShopInMonth.Where(m => m.KPIBonusID == j.ID).FirstOrDefault().Amount, 0));
                        }
                        else
                        {
                            listElementFormula.Add(new ElementFormula(CatElementType.Comission.ToString().ToUpper() + "_" + j.Code, 0, 0));
                        }
                    }
                }
            }

            #region Phần tử lương hoa hồng đã tính được, trong bảng Sal_PaycCommission
            if (CheckIsExistFormula(listElementFormula, formula, "ELEMENT" + CatElementType.Comission.ToString().ToUpper() + "_", ""))
            {
                List<Cat_ElementEntity> listElementByCommission = TotalData.listElement_All.Where(m => m.GradePayrollID == null && m.MethodPayroll == MethodPayroll.E_COMMISSION_PAYMENT.ToString()).ToList();
                if (TotalData.listPayCommissionItem != null)
                {
                    //duyệt wa tất cả các phần tử
                    foreach (var element in listElementByCommission)
                    {
                        string elementCode = element.ElementCode.Replace("ELEMENT" + CatElementType.Comission.ToString().ToUpper() + "_", "");
                        Sal_PayCommissionItemEntity PayCommissionItem = TotalData.listPayCommissionItem.Where(m => m.ProfileID != null && m.Code.ReplaceSpace() == elementCode.ReplaceSpace()).FirstOrDefault();
                        if (PayCommissionItem != null)
                        {
                            item = new ElementFormula(element.ElementCode, PayCommissionItem.Value, 0);
                            listElementFormula.Add(item);
                        }
                        else
                        {
                            item = new ElementFormula(element.ElementCode, 0, 0);
                            listElementFormula.Add(item);
                        }
                    }
                }
                else
                {
                    foreach (var element in listElementByCommission)
                    {
                        item = new ElementFormula(element.ElementCode, 0, 0);
                        listElementFormula.Add(item);
                    }
                }
            }
            #endregion

            #region Lấy dữ liệu các phần tử là tổng số lượng chức vụ (Position) trong shop
            if (CheckIsExistFormula(listElementFormula, formula, CatElementType.Comission.ToString().ToUpper() + "_COUNTPOSITION_", ""))
            {
                using (var context = new VnrHrmDataContext())
                {
                    var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                    var repoProfile = new CustomBaseRepository<Hre_Profile>(unitOfWork);
                    if (TotalData.listPosition != null && TotalData.listPosition.Count > 0)
                    {
                        var lstProfile = repoProfile.FindBy(m => m.ShopID == profileItem.ShopID).ToList();
                        foreach (var j in TotalData.listPosition)
                        {
                            listElementFormula.Add(new ElementFormula(CatElementType.Comission.ToString().ToUpper() + "_COUNTPOSITION_" + j.Code, lstProfile.Where(m => m.PositionID == j.ID).Count(), 0));
                        }
                    }
                }
            }
            #endregion

            #region Lấy giá trị cho 2 enum là dòng sản phẩm và sản phẩm
            if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_COM_PERCENT_SHOP_LINEITEM.ToString(), PayrollElement.SAL_COM_PERCENT_SHOP_ITEM.ToString() }))
            {
                //lấy doanh thu của shop trong tháng
                List<Sal_RevenueRecordEntity> revenueShopInMonth = new List<Sal_RevenueRecordEntity>();
                if (profileItem.ShopID != null)
                {
                    revenueShopInMonth = TotalData.listRevenueRecord.Where(m => m.ShopID == profileItem.ShopID).ToList();
                }

                //SAL_COM_PERCENT_SHOP_5
                if (revenueShopInMonth.Any(m => m.Type == EnumDropDown.SalesType.E_LINEITEM_MAJOR.ToString()))
                {
                    listElementFormula.Add(new ElementFormula(PayrollElement.SAL_COM_PERCENT_SHOP_LINEITEM.ToString(), revenueShopInMonth.Where(m => m.Type == EnumDropDown.SalesType.E_LINEITEM_MAJOR.ToString()).FirstOrDefault().Amount, 0));
                }
                else
                {
                    listElementFormula.Add(new ElementFormula(PayrollElement.SAL_COM_PERCENT_SHOP_LINEITEM.ToString(), 0, 0));
                }

                //SAL_COM_PERCENT_SHOP_6
                if (revenueShopInMonth.Any(m => m.Type == EnumDropDown.SalesType.E_ITEM_MAJOR.ToString()))
                {
                    listElementFormula.Add(new ElementFormula(PayrollElement.SAL_COM_PERCENT_SHOP_ITEM.ToString(), revenueShopInMonth.Where(m => m.Type == EnumDropDown.SalesType.E_ITEM_MAJOR.ToString()).FirstOrDefault().Amount, 0));
                }
                else
                {
                    listElementFormula.Add(new ElementFormula(PayrollElement.SAL_COM_PERCENT_SHOP_ITEM.ToString(), 0, 0));
                }
            }


            #endregion

            #region Tính giá trị cho phần tử khấu trừ khi có nhân viên ko đủ thâm niên trong shop
            if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_COM_BONUS_SCV.ToString()))
            {
                using (var context = new VnrHrmDataContext())
                {
                    var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                    var repoProfile = new CustomBaseRepository<Hre_Profile>(unitOfWork);
                    if (profileItem.ShopID != null)
                    {
                        //tính tiền khấu trừ khi khong đủ thâm niên
                        double Money_Deduction = 0;
                        try
                        {
                            //Hiện tại đang lấy trong webconfig, sau này sẻ lấy trong bảng setting
                            Money_Deduction = (double)GetObjectValue(TotalData.listElement_All, listElementFormula, TotalData.listElement_All.Where(m => m.ElementCode == ConstantPathWeb.Hrm_Sal_ElementName_Comission).FirstOrDefault().Formula);
                        }
                        catch { }

                        if (Money_Deduction != 0)//nhân viên này không đủ thâm niên
                        {
                            if (listTmpDeduction.Any(m => m.Key == profileItem.ShopID))//đã có nhân viên ko đủ thâm niên trong shop trước đó
                            {
                                double _tmp = listTmpDeduction.Single(m => m.Key == profileItem.ShopID).Value.Value;
                                int countValue = listTmpDeduction.Single(m => m.Key == profileItem.ShopID).Value.Count;
                                listTmpDeduction.Remove((Guid)profileItem.ShopID);//xóa phần tử trước đó
                                listTmpDeduction.Add((Guid)profileItem.ShopID, new ValueCount(Money_Deduction + _tmp, countValue++));//thêm lại phần tử đó và cập nhật lại value
                            }
                            else//là nhân viên ko đủ thâm niên đầu tiên trong shop
                            {
                                listTmpDeduction.Add((Guid)profileItem.ShopID, new ValueCount(Money_Deduction, 1));//thêm lại phần tử đó và cập nhật lại value
                            }
                            item = new ElementFormula(PayrollElement.SAL_COM_BONUS_SCV.ToString(), 0, 0);
                            listElementFormula.Add(item);
                        }
                        else//nhân viên này đủ thâm niên, kiểm tra xem shop của nhân viên này có nhân viên nào ko đủ thâm niên hay không
                        {
                            if (listTmpDeduction.Any(m => m.Key == profileItem.ShopID))//đã có nhân viên ko đủ thâm niên trong shop trước đó
                            {
                                int CountProfile = repoProfile.FindBy(m => m.ShopID == profileItem.ShopID).Count() - listTmpDeduction.Single(m => m.Key == profileItem.ShopID).Value.Count;
                                item = new ElementFormula(PayrollElement.SAL_COM_BONUS_SCV.ToString(), listTmpDeduction.Single(m => m.Key == profileItem.ShopID).Value.Value / CountProfile, 0);
                                listElementFormula.Add(item);
                            }
                            else
                            {
                                item = new ElementFormula(PayrollElement.SAL_COM_BONUS_SCV.ToString(), 0, 0);
                                listElementFormula.Add(item);
                            }
                        }
                    }
                    else
                    {
                        item = new ElementFormula(PayrollElement.SAL_COM_BONUS_SCV.ToString(), 0, 0);
                        listElementFormula.Add(item);
                    }
                }
            }

            #endregion

            #endregion

            #region lấy các phần tử Đánh Giá

            if (CheckIsExistFormula(listElementFormula, formula, CatElementType.Evaluation.ToString().ToUpper(), ""))
            {
                IList<string> List_EvaBonusType = Enum.GetValues(typeof(EvaBonusType))
                                          .Cast<EvaBonusType>()
                                          .Select(x => x.ToString())
                                          .ToList();

                if (TotalData.listSalesType != null && TotalData.listSalesType.Count > 0)
                {
                    foreach (var j in TotalData.listSalesType)
                    {
                        foreach (var t in List_EvaBonusType)
                        {
                            try
                            {
                                Eva_BonusSalaryEntity BonusSalaryITem = TotalData.listEva_BonusSalary.Where(m => m.ProfileID == profileItem.ID
                                    && m.SalesTypeID == j.ID
                                    && m.Type == t).FirstOrDefault();
                                if (BonusSalaryITem != null && BonusSalaryITem.Bonus != null)
                                {
                                    item = new ElementFormula(CatElementType.Evaluation.ToString().ToUpper() + "_" + j.Code + "_" + t, BonusSalaryITem.Bonus, 0);
                                    listElementFormula.Add(item);
                                }
                                else
                                {
                                    item = new ElementFormula(CatElementType.Evaluation.ToString().ToUpper() + "_" + j.Code + "_" + t, 0, 0);
                                    listElementFormula.Add(item);
                                }
                            }
                            catch
                            {
                                item = new ElementFormula(CatElementType.Evaluation.ToString().ToUpper() + "_" + j.Code + "_" + t, 0, 0);
                                listElementFormula.Add(item);
                            }
                        }
                    }
                }
            }
            #endregion

            #region Vietject

            #region Lấy các phần tử đơn giá theo vai trò (Vietject)

            if (CheckIsExistFormula(listElementFormula, formula, CatElementType.FLIGHT.ToString() + "_", "_HOURS") ||
                CheckIsExistFormula(listElementFormula, formula, CatElementType.FLIGHT.ToString() + "_", "_ROUTES") ||
                CheckIsExistFormula(listElementFormula, formula, CatElementType.FLIGHT.ToString() + "_", "_AMOUNT"))
            {
                List<Att_TimeSheetEntity> Att_TimeSheetItem = TotalData.listAtt_TimeSheet.Where(m => m.ProfileID == profileItem.ID && m.Date <= CutOffDuration.DateEnd && m.Date >= CutOffDuration.DateStart).OrderByDescending(m => m.Date).ToList();
                List<Cat_UnitPriceEntity> Cat_UnitPrice = TotalData.listCat_UnitPrice.Where(m => m.Date <= CutOffDuration.DateEnd).OrderByDescending(m => m.Date).ToList();
                if (TotalData.listCat_Role != null && TotalData.listCat_Role.Count > 0 && TotalData.listCat_JobType != null && TotalData.listCat_JobType.Count > 0)
                {
                    foreach (var Role in TotalData.listCat_Role)
                    {
                        foreach (var JobType in TotalData.listCat_JobType)
                        {
                            var Att_TimeSheetItemByItem = Att_TimeSheetItem.Where(m => m.RoleID == Role.ID && m.JobTypeID == JobType.ID).OrderByDescending(m => m.Date).ToList();
                            var Cat_UnitPriceByItem = Cat_UnitPrice.Where(m => m.RoleID == Role.ID && m.JobTypeID == JobType.ID).OrderByDescending(m => m.Date).FirstOrDefault();
                            //số giờ bay
                            item = new ElementFormula(CatElementType.FLIGHT.ToString() + "_" + Role.Code.ReplaceSpace() + "_" + JobType.Code.ReplaceSpace() + "_HOURS", Att_TimeSheetItemByItem.Sum(m => m.NoHour), 0);
                            listElementFormula.Add(item);
                            //số chặn bay
                            item = new ElementFormula(CatElementType.FLIGHT.ToString() + "_" + Role.Code.ReplaceSpace() + "_" + JobType.Code.ReplaceSpace() + "_ROUTES", Att_TimeSheetItemByItem.Sum(m => m.Sector), 0);
                            listElementFormula.Add(item);

                            //số tiền
                            double Amount = Cat_UnitPriceByItem != null && Cat_UnitPriceByItem.Amount != null ? (double)Cat_UnitPriceByItem.Amount : 0;
                            item = new ElementFormula(CatElementType.FLIGHT.ToString() + "_" + Role.Code.ReplaceSpace() + "_" + JobType.Code.ReplaceSpace() + "_AMOUNT", Amount, 0);
                            listElementFormula.Add(item);
                        }
                    }
                }
            }
            #endregion

            #endregion

            return listElementFormula.Distinct().ToList();
        }
        public List <Att_OvertimeEntity> LoadData(Att_OvertimeEntity overtime, string ProfileIds, bool ByShiftProfile, string UserLogin)
        {
            List <Att_OvertimeEntity> listOvertimeInsert = new List <Att_OvertimeEntity>();

            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork        = (IUnitOfWork)(new UnitOfWork(context));
                var repoCat_DayOff    = new CustomBaseRepository <Cat_DayOff>(unitOfWork);
                var repoAtt_LeaveDay  = new CustomBaseRepository <Att_LeaveDay>(unitOfWork);
                var repoAtt_Pregnancy = new CustomBaseRepository <Att_Pregnancy>(unitOfWork);

                List <Att_Pregnancy> _LstPregnancy = new List <Att_Pregnancy>();
                Att_OvertimeServices overtimeDAO   = new Att_OvertimeServices();
                string status = string.Empty;

                string      proStr            = Common.DotNetToOracle(ProfileIds);
                var         lstProfileDetails = GetData <Hre_ProfileEntity>(proStr, ConstantSql.hrm_hr_sp_get_ProfileByIds, UserLogin, ref status);
                List <Guid> listProfileId     = lstProfileDetails.Select(s => s.ID).ToList();

                string        key      = "HRM_ATT_OT";
                List <object> lstSysOT = new List <object>();
                lstSysOT.Add(key);
                lstSysOT.Add(null);
                lstSysOT.Add(null);
                var config = GetData <Sys_AllSettingEntity>(lstSysOT, ConstantSql.hrm_sys_sp_get_AllSetting, UserLogin, ref status);
                if (config == null)
                {
                    return(listOvertimeInsert);
                }

                var OTThanTwoHour     = config.Where(s => s.Name == AppConfig.HRM_ATT_OT_ISALLOWADDHOURWHENOTTHANTWOHOUR.ToString()).FirstOrDefault();
                var OTBreakTime       = config.Where(s => s.Name == AppConfig.HRM_ATT_OT_DONOTSPLITOTBREAKTIME.ToString()).FirstOrDefault();
                var inmaternityregime = config.Where(s => s.Name == AppConfig.HRM_ATT_OT_ALLOWREGISTEROTWHENINMATERNITYREGIME.ToString()).FirstOrDefault();


                List <Cat_DayOff> lstDayOff = repoCat_DayOff.FindBy(s => s.IsDelete == null).ToList();
                if (OTThanTwoHour.Value1 == bool.TrueString)
                {
                    lstDayOff = lstDayOff.Where(dayoff => dayoff.Type == HolidayType.E_HOLIDAY_HLD.ToString()).ToList();
                }

                bool isAllowCutOTBreakHour = false;
                if (OTBreakTime.Value1 == bool.TrueString)
                {
                    isAllowCutOTBreakHour = true;
                }

                Att_OvertimeEntity baseOT = null;

                //Trung.Le 20120621 #0014337 Nếu như CÓ THÊM đăng ký Leave loại nghỉ lễ (Mã: HLD) thì ngày đó tương đương với ngày nghỉ lễ
                string              LeavedayTypeCode_HLD = LeavedayTypeCode.HLD.ToString();
                string              E_HOLIDAY_HLD        = HolidayType.E_HOLIDAY_HLD.ToString();
                DateTime            DateFromOvertime     = overtime.WorkDate.Date;
                DateTime            DateEndOvertime      = overtime.WorkDate.Add(TimeSpan.FromHours(overtime.RegisterHours)).Date;
                string              E_APPROVED           = LeaveDayStatus.E_APPROVED.ToString();
                List <Att_LeaveDay> lstLeaveDayHoliday   = repoAtt_LeaveDay
                                                           .FindBy(att => att.IsDelete == null && DateEndOvertime >= att.DateStart && DateFromOvertime <= att.DateEnd &&
                                                                   att.Status == E_APPROVED && att.Cat_LeaveDayType.Code == LeavedayTypeCode_HLD &&
                                                                   listProfileId.Contains(att.ProfileID))
                                                           .ToList();


                if (overtime.ID == Guid.Empty)
                {
                    //baseOT = GetBaseDataOvertime(baseOT, overtime, profile);
                    string _pregnancyType = PregnancyType.E_LEAVE_EARLY.ToString();
                    _LstPregnancy = repoAtt_Pregnancy
                                    .FindBy(prg => prg.Type == _pregnancyType && prg.DateEnd >= overtime.WorkDate.Date && prg.DateStart <= overtime.WorkDate)
                                    .ToList();

                    Hre_Profile _hreProfile = new Hre_Profile();
                    foreach (var profile in lstProfileDetails)
                    {
                        overtime.ProfileID   = profile.ID;
                        overtime.ProfileName = profile.ProfileName;
                        overtime.CodeEmp     = profile.CodeEmp;

                        listOvertimeInsert.AddRange(AnalysisOvertime(overtime,
                                                                     GetListDayOffPerProfile(lstLeaveDayHoliday, profile, lstDayOff, E_HOLIDAY_HLD) //lstDayOff
                                                                     , _LstPregnancy, ByShiftProfile, isAllowCutOTBreakHour, UserLogin));
                    }
                }
                #region overtime.ID == Guid.Empty && strListId.Length > 1
                //if (overtime.ID == Guid.Empty && strListId.Length > 1)
                //{
                //    List<Hre_Profile> listAllProfile = EntityService.GetEntityList<Hre_Profile>(GuidContext, LoginUserID.Value, pf => listProfileId.Contains(pf.ID));
                //    foreach (Guid _pfID in listProfileId)
                //    {
                //        if (_pfID != pfid)
                //        {
                //            baseOT = GetBaseDataOvertime(baseOT, overtime, profile);

                //            List<Hre_Profile> _listPfTemp = listAllProfile.Where(pf => pf.ID == _pfID).ToList();
                //            if (_listPfTemp.Count != 1)
                //            {
                //                continue;
                //            }
                //            profile = _listPfTemp[0];
                //            baseOT.Hre_Profile = profile;
                //            listOvertimeInsert.AddRange(overtimeDAO.AnalysisOvertime(baseOT,
                //                GetListDayOffPerProfile(lstLeaveDayHoliday, profile, lstDayOff, E_HOLIDAY_HLD) //lstDayOff
                //                , _LstPregnancy, GuidContext, LoginUserID.Value, rdbByShiftProfile, isAllowCutOTBreakHour));
                //        }
                //    }
                //}
                #endregion
                #region tan.do danh dau nguoi huong che do thai san
                //_listbaseData = new List<BaseDataOvertime>();
                if (inmaternityregime.Value1 != bool.TrueString)
                {
                    DateTime    time        = overtime.WorkDate;
                    string      type        = PregnancyStatus.E_LEAVE_EARLY.ToString();
                    List <Guid> guids       = listOvertimeInsert.Select(s => s.ProfileID).ToList();
                    var         pregnancies = repoAtt_Pregnancy
                                              .FindBy(s => s.IsDelete == null && s.DateStart <= time && time <= s.DateEnd && s.Type == type &&
                                                      guids.Contains(s.ProfileID))
                                              .ToList();
                    foreach (var baseDataOvertime in listOvertimeInsert)
                    {
                        foreach (var attPregnancy in pregnancies)
                        {
                            if (baseDataOvertime.ProfileID == attPregnancy.ProfileID)
                            {
                                //_listbaseData.Add(baseDataOvertime);
                            }
                        }
                    }
                }
                #endregion
                return(listOvertimeInsert);
            }
        }
        /// <summary>
        /// Button Tìm Kiếm Phép Bệnh
        /// </summary>
        /// <param name="Year"></param>
        /// <param name="orgStructure"></param>
        /// <param name="LstProfileStatus"></param>
        /// <returns></returns>
        public List<Att_AnnualLeaveDetailEntity> SearchAnnualSickLeaveDetail(int Year, string orgStructure, string LstProfileStatus, string UserLogin)
        {
            using (var context = new VnrHrmDataContext())
            {
                string status = string.Empty;
                var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                var repoAtt_AnnualLeaveDetail = new CustomBaseRepository<Att_AnnualLeaveDetail>(unitOfWork);
                var repoHre_Profile = new CustomBaseRepository<Hre_Profile>(unitOfWork);
                var repoHre_HDTJob = new CustomBaseRepository<Hre_HDTJob>(unitOfWork);

                string E_SICK_LEAVE = AnnualLeaveDetailType.E_SICK_LEAVE.ToString();

                Att_AnnualLeaveDetail AnnualLeaveDetailTop = AnnualLeaveDetailTop = repoAtt_AnnualLeaveDetail
                    .FindBy(m => m.IsDelete == null && m.Type == E_SICK_LEAVE && m.Year == Year).FirstOrDefault();
                if (AnnualLeaveDetailTop == null)
                {
                    return new List<Att_AnnualLeaveDetailEntity>();
                }
                DateTime beginyear = (AnnualLeaveDetailTop == null || AnnualLeaveDetailTop.MonthStart == null) ? new DateTime(Year, 1, 1) : AnnualLeaveDetailTop.MonthStart.Value;
                DateTime endYear = beginyear.AddYears(1).AddMinutes(-1);

                List<object> lstObj = new List<object>();
                lstObj.Add(orgStructure);
                lstObj.Add(null);
                lstObj.Add(null);
                var lstProfileQuery = GetData<Hre_ProfileEntity>(lstObj, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, UserLogin, ref status).ToList();

                if (LstProfileStatus != null)
                {
                    if (LstProfileStatus == StatusEmpLeaveDetail.E_NEWEMPINYEAR.ToString())
                    {
                        lstProfileQuery = lstProfileQuery.Where(m => m.DateHire != null && m.DateHire >= beginyear && m.DateHire <= endYear).ToList();
                    }
                    if (LstProfileStatus == StatusEmpLeaveDetail.E_RESIGNEMPINYEAR.ToString())
                    {
                        lstProfileQuery = lstProfileQuery.Where(m => m.DateQuit != null && m.DateQuit >= beginyear && m.DateQuit <= endYear).ToList();
                    }
                    if (LstProfileStatus == StatusEmpLeaveDetail.E_EMPOFHDT4.ToString())
                    {
                        string Job4 = HDTJobType.E_Four.ToString();
                        List<Guid> lstprofileHDT4 = repoHre_HDTJob
                            .FindBy(m => m.IsDelete == null && m.Type == Job4 && m.DateFrom <= endYear && m.DateTo >= beginyear && m.ProfileID != null)
                            .Select(m => m.ProfileID.Value).ToList<Guid>();
                        lstProfileQuery = lstProfileQuery.Where(m => lstprofileHDT4.Contains(m.ID)).ToList();
                    }
                    if (LstProfileStatus == StatusEmpLeaveDetail.E_EMPOFHDT5.ToString())
                    {
                        string Job5 = HDTJobType.E_Five.ToString();
                        List<Guid> lstprofileHDT5 = repoHre_HDTJob
                            .FindBy(m => m.IsDelete == null && m.Type == Job5 && m.DateFrom <= endYear && m.DateTo >= beginyear && m.ProfileID != null)
                            .Select(m => m.ProfileID.Value).ToList<Guid>();
                        lstProfileQuery = lstProfileQuery.Where(m => lstprofileHDT5.Contains(m.ID)).ToList();
                    }
                }

                List<Guid> lstProfileID = lstProfileQuery.Select(m => m.ID).Distinct().ToList<Guid>();
                List<Att_AnnualLeaveDetailEntity> lstAnnDetail = repoAtt_AnnualLeaveDetail
                    .FindBy(m => m.IsDelete == null && m.Type == E_SICK_LEAVE && m.Year == Year
                    && m.ProfileID != null && lstProfileID.Contains(m.ProfileID.Value)).ToList().Translate<Att_AnnualLeaveDetailEntity>();

                foreach (var ann in lstAnnDetail)
                {
                    var pro = lstProfileQuery.Where(s => s.ID == ann.ProfileID).FirstOrDefault();

                    ann.ProfileName = pro.ProfileName ?? string.Empty;
                    ann.CodeEmp = pro.CodeEmp ?? string.Empty;
                    ann.OrgStructureName = pro.OrgStructureName ?? string.Empty;
                    ann.DateHire = pro.DateHire ?? null;
                }
                return lstAnnDetail;

            }
        }
Beispiel #47
0
        public List <Can_MealRecordEntity> GetMealRecordSummary(string _line, string _catering, string _canteen, DateTime dateStart, DateTime dateEnd, List <Hre_ProfileEntity> lstProfileIDs, string UserLogin)
        {
            dateStart = dateStart.Date;
            dateEnd   = dateEnd.Date.AddDays(1).AddMilliseconds(-1);

            using (var context = new VnrHrmDataContext())
            {
                var    unitOfWork         = (IUnitOfWork)(new UnitOfWork(context));
                var    repoCan_MealRecord = new CustomBaseRepository <Can_MealRecord>(unitOfWork);
                var    repoCan_TamScanLog = new CustomBaseRepository <Can_TamScanLogCMS>(unitOfWork);
                var    repoCan_Line       = new CustomBaseRepository <Can_Line>(unitOfWork);
                var    repoCan_Canteen    = new CustomBaseRepository <Can_Canteen>(unitOfWork);
                var    repoCan_Catering   = new CustomBaseRepository <Can_Catering>(unitOfWork);
                var    repoSys_AllSetting = new CustomBaseRepository <Sys_AllSetting>(unitOfWork);
                string status             = string.Empty;
                //string strIDs = string.Join(",", lstProfileIDs.ToArray());
                #region xử lý cấu hình giờ kết thúc ăn - DateStart & DateEnd
                DateTime dateConfig   = DateTime.MinValue;
                var      rsTimeConfig = GetData <Sys_AllSettingEntity>(AppConfig.HRM_CAN_MEALRECORD_EATEND_CONFIG.ToString(), ConstantSql.hrm_sys_sp_get_AllSettingByKey, UserLogin, ref status).FirstOrDefault();
                if (rsTimeConfig != null && rsTimeConfig.Value1 != null)
                {
                    dateConfig = DateTimeHelper.ConvertStringToDateTime(rsTimeConfig.Value1, ConstantFormat.HRM_Format_YearMonthDay_HoursMinSecond_ffffff.ToString());
                }
                double hourConfig = dateConfig.Hour + (((double)dateConfig.Minute) / 60);
                dateStart = dateStart.Date.AddHours(hourConfig);
                dateEnd   = dateEnd.Date.AddDays(1).AddHours(hourConfig).AddMilliseconds(-1);
                #endregion

                #region cấu hình số phút xử lý trùng
                int rsScanMulti       = 0;
                var rsScanMultiConfig = GetData <Sys_AllSettingEntity>(AppConfig.HRM_CAN_MEALRECORD_SCANMULTI_CONFIG.ToString(), ConstantSql.hrm_sys_sp_get_AllSettingByKey, UserLogin, ref status).FirstOrDefault();

                if (rsScanMultiConfig != null)
                {
                    rsScanMulti = rsScanMultiConfig.Value1 != null?int.Parse(rsScanMultiConfig.Value1.ToString()) : 0;
                }
                #endregion

                var tamScanLogs = repoCan_TamScanLog
                                  .FindBy(s => dateStart <= s.TimeLog && s.TimeLog <= dateEnd)
                                  .Select(s => new { s.MachineCode, s.CardCode, s.TimeLog, s.ID })
                                  .ToList();
                var cardCodes = tamScanLogs.Select(s => s.CardCode).ToList();

                //strIDs = Common.DotNetToOracle(strIDs);
                //var profiles = GetData<Hre_ProfileEntity>(strIDs, ConstantSql.hrm_hr_sp_get_ProfileByIds, ref status)
                //    .Where(s => cardCodes.Contains(s.CodeAttendance) && lstProfileIDs.Contains(s.ID))
                var profiles = lstProfileIDs
                               .Where(s => cardCodes.Contains(s.CodeAttendance))
                               .Select(s => new { s.ID, s.CodeAttendance, s.CodeEmp, s.ProfileName, s.OrgStructureName }).ToList();

                tamScanLogs = tamScanLogs.Where(s => profiles.Select(p => p.CodeAttendance).Contains(s.CardCode)).OrderBy(s => s.CardCode).ThenBy(s => s.TimeLog).ToList();
                var lines     = repoCan_Line.FindBy(s => s.IsDelete == null).ToList();
                var canteens  = repoCan_Canteen.FindBy(s => s.IsDelete == null).ToList();
                var caterings = repoCan_Catering.FindBy(s => s.IsDelete == null).ToList();
                if (_line != null)
                {
                    List <Guid> lstLine = _line.Split(',').Select(Guid.Parse).ToList();
                    lines = lines.Where(s => lstLine.Contains(s.ID)).ToList();
                }
                if (_canteen != null)
                {
                    List <Guid> lstcanteen = _canteen.Split(',').Select(Guid.Parse).ToList();
                    canteens = canteens.Where(s => lstcanteen.Contains(s.ID)).ToList();
                }
                if (_catering != null)
                {
                    List <Guid> lstcatering = _catering.Split(',').Select(Guid.Parse).ToList();
                    caterings = caterings.Where(s => lstcatering.Contains(s.ID)).ToList();
                }

                List <object> lstObj = new List <object>();
                lstObj.Add(dateStart);
                lstObj.Add(dateEnd);
                List <Can_MealRecordCheckEntity> mealRecordCheckList = GetData <Can_MealRecordCheckEntity>(lstObj, ConstantSql.hrm_can_sp_get_MealRecord_ByDateFromDateTo, UserLogin, ref status);
                Can_MealRecordEntity             record    = new Can_MealRecordEntity();
                List <Can_MealRecordEntity>      lstRecord = new List <Can_MealRecordEntity>();
                List <Can_MealRecord>            lstEdit   = new List <Can_MealRecord>();
                List <Can_MealRecord>            lstAdd    = new List <Can_MealRecord>();

                List <Guid> lstDuplicateTamScan = new List <Guid>();
                foreach (var tamScanLog in tamScanLogs)
                {
                    if (lstDuplicateTamScan.Contains(tamScanLog.ID))
                    {
                        continue;
                    }

                    record = new Can_MealRecordEntity();
                    var profile = profiles.FirstOrDefault(s => s.CodeAttendance == tamScanLog.CardCode);
                    var line    = lines.FirstOrDefault(s => tamScanLog.MachineCode == s.MachineCode);

                    if (profile != null && line != null)
                    {
                        #region xử lý quẹt thẻ trùng theo HRM_CAN_MEALRECORD_SCANMULTI_CONFIG
                        var tamScanLogProfiles = tamScanLogs
                                                 .Where(s => s.CardCode == tamScanLog.CardCode && s.TimeLog.Value.Date == tamScanLog.TimeLog.Value.Date && s.MachineCode == tamScanLog.MachineCode)
                                                 .OrderBy(s => s.TimeLog)
                                                 .ToList();

                        if (tamScanLogProfiles.Count > 1 && rsScanMulti > 0)
                        {
                            for (int i = 0; i < tamScanLogProfiles.Count; i++)
                            {
                                var tamsanFirst = tamScanLogProfiles[i];
                                int j           = i + 1;
                                if (j > tamScanLogProfiles.Count - 1)
                                {
                                    j = i;
                                }
                                var tamsanNear = tamScanLogProfiles[j];

                                if (tamsanNear.TimeLog.Value.Subtract(tamsanFirst.TimeLog.Value).TotalMinutes < rsScanMulti &&
                                    tamsanFirst.ID != tamsanNear.ID)
                                {
                                    if (tamsanFirst.MachineCode == tamsanNear.MachineCode)
                                    {
                                        lstDuplicateTamScan.Add(tamsanNear.ID);
                                        break;
                                    }
                                }
                            }
                        }
                        #endregion

                        #region xử lý add record
                        record.TimeLog = tamScanLog.TimeLog.HasValue ? tamScanLog.TimeLog.Value : DateTime.MinValue;
                        if (record.TimeLog < record.TimeLog.Value.Date.AddHours(hourConfig))
                        {
                            record.WorkDay = record.TimeLog.Value.AddDays(-1);
                        }
                        else
                        {
                            record.WorkDay = record.TimeLog;
                        }

                        if (tamScanLog.MachineCode != null)
                        {
                            record.MachineCode = tamScanLog.MachineCode;
                            if (line != null)
                            {
                                record.LineName = line.LineName;
                                record.LineID   = line.ID;
                                record.Amount   = (decimal)line.Amount;
                                if (line.CanteenID != null)
                                {
                                    var cant = canteens.Where(c => c.ID == line.CanteenID).FirstOrDefault();
                                    record.CanteenName = cant.CanteenName;
                                    record.CanteenID   = line.CanteenID;
                                }
                                if (line.CateringID != null)
                                {
                                    var cater = caterings.Where(c => c.ID == line.CateringID).FirstOrDefault();
                                    record.CateringName = cater.CateringName;
                                    record.CateringID   = line.CateringID;
                                }
                            }
                        }

                        record.ProfileName      = profile.ProfileName;
                        record.CodeEmp          = profile.CodeEmp;
                        record.OrgStructureName = profile.OrgStructureName;
                        record.CodeAttendance   = profile.CodeAttendance;
                        record.DateCreate       = DateTime.Now;

                        var recordAdd = record.CopyData <Can_MealRecord>();
                        recordAdd.ProfileID = profile.ID;
                        var CheckList = mealRecordCheckList.Where(s => s.ProfileID == profile.ID && s.TimeLog == tamScanLog.TimeLog).ToList();
                        if (CheckList != null)
                        {
                            if (CheckList.Count() > 0)
                            {
                                var idUpdate = CheckList.FirstOrDefault();
                                recordAdd.ID = idUpdate.ID;
                                //lstEdit.Add(recordAdd);
                                repoCan_MealRecord.Edit(recordAdd);
                            }
                            else
                            {
                                recordAdd.ID = Guid.NewGuid();
                                repoCan_MealRecord.Add(recordAdd);
                                //lstAdd.Add(recordAdd);
                            }
                        }
                        record.ID = tamScanLog.ID;
                        lstRecord.Add(record);
                        #endregion
                    }
                }

                repoCan_MealRecord.SaveChanges();


                if (lstRecord.Count > 0)
                {
                    Sys_AllSetting sys = new Sys_AllSetting();
                    Sys_AllSetting rs  = GetData <Sys_AllSetting>(AppConfig.HRM_CAN_MEALRECORD_SUMMARY.ToString(), ConstantSql.hrm_sys_sp_get_AllSettingByKey, UserLogin, ref status).FirstOrDefault();
                    sys.Value1 = dateStart.ToString(ConstantFormat.HRM_Format_YearMonthDay_HoursMinSecond.ToString());
                    sys.Value2 = dateEnd.ToString(ConstantFormat.HRM_Format_YearMonthDay_HoursMinSecond.ToString());
                    sys.Name   = AppConfig.HRM_CAN_MEALRECORD_SUMMARY.ToString();

                    if (rs != null)
                    {
                        sys.ID = rs.ID;
                        repoSys_AllSetting.Edit(sys);
                    }
                    else
                    {
                        sys.ID = Guid.NewGuid();
                        repoSys_AllSetting.Add(sys);
                    }
                    repoSys_AllSetting.SaveChanges();
                }
                //lstRecord.Where().(s => s.MealAllowanceTypeName = ConstantDisplay.HRM_Enum_Submit.TranslateString()).ToList();
                return(lstRecord);
            }
        }
Beispiel #48
0
 public bool SaveCustomAccumulate(Guid ID, double AccumulateRevice)
 {
     using (var context = new VnrHrmDataContext())
     {
         try
         {
             var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
             string status = string.Empty;
             var repoKai_KaizenData = new CustomBaseRepository<Kai_KaizenData>(unitOfWork);
             Kai_KaizenData KaiZendData = repoKai_KaizenData.FindBy(m => m.ID == ID).FirstOrDefault();
             KaiZendData.AccumulateRevice = AccumulateRevice;
             unitOfWork.SaveChanges();
             return true;
         }
         catch
         {
             return false;
         }
     }
 }
Beispiel #49
0
        public string ImportTrainee(List <ImportTraineeEntity> lstImport, string UserLogin)
        {
            int NumTrainee = 0;
            var message    = string.Empty;

            using (var context = new VnrHrmDataContext())
            {
                string status               = string.Empty;
                var    services             = new Tra_TraineeServices();
                var    unitOfWork           = (IUnitOfWork)(new UnitOfWork(context));
                var    repoTra_Class        = new CustomBaseRepository <Tra_Class>(unitOfWork);
                var    repoTra_CourseTopic  = new CustomBaseRepository <Tra_CourseTopic>(unitOfWork);
                var    repoTra_Trainee      = new CustomBaseRepository <Tra_Trainee>(unitOfWork);
                var    repoTra_TraineeTopic = new CustomBaseRepository <Tra_TraineeTopic>(unitOfWork);
                var    repoHre_Profile      = new CustomBaseRepository <Hre_Profile>(unitOfWork);
                var    lstTraineeAdd        = new List <Tra_TraineeEntity>();
                var    lstTraineeTopicAdd   = new List <Tra_TraineeTopicEntity>();
                var    entity               = new List <Tra_Trainee>();
                var    lstClassCode         = lstImport.Select(m => m.ClassCode).Distinct().ToList();
                var    lstClass             = repoTra_Class.FindBy(m => m.IsDelete == null &&
                                                                   (lstClassCode.Contains(m.Code)))
                                              .Select(m => new { m.ID, m.CourseID, m.Code }).ToList();
                var lstCourseID    = lstClass.Select(m => m.CourseID).Distinct().ToList();
                var lstCourseTopic = repoTra_CourseTopic.FindBy(m => m.IsDelete == null &&
                                                                (lstCourseID.Contains(m.CourseID))).Select(m => new { m.ID, m.CourseID, m.TopicID }).ToList();
                var lstProfileCode = lstImport.Select(m => m.CodeEmp).Distinct().ToList();
                var lstProfile     = repoHre_Profile.FindBy(m => m.IsDelete == null && lstProfileCode.Contains(m.CodeEmp)).Select(m => new { m.ID, m.CodeEmp }).ToList();

                var requirementServices = new Tra_RequirementTrainServices();
                var objRequirement      = new List <object>();
                objRequirement.AddRange(new object[7]);
                objRequirement[5] = 1;
                objRequirement[6] = int.MaxValue - 1;
                var lstRequirement = requirementServices.GetData <Tra_RequirementTrainEntity>(objRequirement, ConstantSql.hrm_tra_sp_get_RequirementTrain, UserLogin, ref status).ToList();

                var requirementDetailServices = new Tra_RequirementTrainDetailServices();
                var objRequirementDetail      = new List <object>();
                objRequirementDetail.Add(null);
                objRequirementDetail.Add(1);
                objRequirementDetail.Add(int.MaxValue - 1);
                var lstRequirementDetail = requirementDetailServices.GetData <Tra_RequirementTrainDetailEntity>(objRequirementDetail, ConstantSql.hrm_tra_sp_get_RequirementDetail, UserLogin, ref status).ToList();

                List <Tra_Trainee>      lstTrainee      = new List <Tra_Trainee>();
                List <Tra_TraineeTopic> lstTraineeTopic = new List <Tra_TraineeTopic>();


                foreach (var item in lstImport)
                {
                    var traClass = lstClass.Where(m => m.Code == item.ClassCode).FirstOrDefault();
                    if (traClass == null)
                    {
                        continue;
                    }
                    var requirementEntity = lstRequirement.Where(s => s.Code == item.RequirementCode).FirstOrDefault();
                    if (requirementEntity == null)
                    {
                        continue;
                    }
                    var requirementDetailEntity = lstRequirementDetail.Where(s => s.CourseID != null && lstCourseID.Contains(s.CourseID.Value) && s.ProfileID != null && !string.IsNullOrEmpty(s.CodeEmp) && item.CodeEmp == s.CodeEmp).FirstOrDefault();
                    if (requirementDetailEntity == null)
                    {
                        continue;
                    }

                    var profile = lstProfile.Where(m => m.CodeEmp == item.CodeEmp).FirstOrDefault();
                    if (profile == null)
                    {
                        continue;
                    }

                    Tra_Trainee trainee = new Tra_Trainee();
                    trainee.ID        = Guid.NewGuid();
                    trainee.ClassID   = traClass.ID;
                    trainee.ProfileID = profile.ID;
                    trainee.Status    = item.Status;
                    lstTrainee.Add(trainee);
                    if (traClass.CourseID != null)
                    {
                        List <Guid> lstTopicIDs = lstCourseTopic.Where(m => m.CourseID == traClass.CourseID).Select(m => m.TopicID).ToList();
                        foreach (var topic in lstTopicIDs)
                        {
                            Tra_TraineeTopic traineeTopic = new Tra_TraineeTopic();
                            traineeTopic.ID          = Guid.NewGuid();
                            traineeTopic.Tra_Trainee = trainee;
                            traineeTopic.TraineeID   = (Guid?)trainee.ID;
                            traineeTopic.TopicID     = topic;
                            lstTraineeTopic.Add(traineeTopic);
                        }
                    }
                    if (requirementDetailEntity != null && traClass != null)
                    {
                        requirementDetailEntity.ClassID = (Guid?)traClass.ID;
                        message = Edit(requirementDetailEntity);
                    }
                }

                lstTraineeAdd      = lstTrainee.Translate <Tra_TraineeEntity>();
                lstTraineeTopicAdd = lstTraineeTopic.Translate <Tra_TraineeTopicEntity>();
                NumTrainee         = lstTrainee.Count;
                message            = Add(lstTraineeAdd);
                message            = Add(lstTraineeTopicAdd);
            }

            return(message);
        }
Beispiel #50
0
        public int[] ApprevedKaiZenData(List<Guid> selectedIds, DateTime MonthYear, Guid UnusualEDTypeID, Guid Currency)
        {
            using (var context = new VnrHrmDataContext())
            {
                string status = string.Empty;
                var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                var repoKai_KaizenData = new CustomBaseRepository<Kai_KaizenData>(unitOfWork);
                var repoSal_UnusualAllowance = new CustomBaseRepository<Sal_UnusualAllowance>(unitOfWork);
                List<Sal_UnusualAllowance> listUnusualAllowance = new List<Sal_UnusualAllowance>();

                //lọc ra các kaizen được chọn
                List<Kai_KaizenData> listKaiZendata = repoKai_KaizenData.FindBy(m => m.IsDelete != true).ToList();
                listKaiZendata = listKaiZendata.Where(m => m.Status == EnumDropDown.Kai_KaizenDataStatus.E_APPROVED.ToString() && selectedIds.Any(t => t == m.ID)).ToList();

                int Pass = 0;
                int Fail = 0;

                Sal_UnusualAllowance item = new Sal_UnusualAllowance();
                foreach (var KaiZenItem in listKaiZendata)
                {
                    if (KaiZenItem.DateTransferPayment == null && (KaiZenItem.IsPaymentOut == null || KaiZenItem.IsPaymentOut == false))
                    {
                        item = new Sal_UnusualAllowance();
                        item.ProfileID = KaiZenItem.ProfileID != null ? (Guid)KaiZenItem.ProfileID : Guid.NewGuid();
                        item.MonthStart = new DateTime(MonthYear.Year, MonthYear.Month, 1);
                        item.MonthEnd = new DateTime(MonthYear.Year, MonthYear.Month, 1).AddMonths(1).AddDays(-1);
                        item.Type = EnumDropDown.EDType.E_EARNING.ToString();
                        item.UnusualEDTypeID = UnusualEDTypeID;
                        item.CurrencyID = Currency;
                        item.Amount = KaiZenItem.SumAmount != null ? KaiZenItem.SumAmount : 0;
                        listUnusualAllowance.Add(item);

                        KaiZenItem.DateTransferPayment = MonthYear;
                        Pass++;
                    }
                    else
                    {
                        Fail++;
                    }
                }
                repoSal_UnusualAllowance.Add(listUnusualAllowance);
                unitOfWork.SaveChanges();
                return new int[] { Pass, Fail };
            }
        }
Beispiel #51
0
        public string[] SetWaitApproveKaiZenData(List<Guid> SelectIds)
        {
            using (var context = new VnrHrmDataContext())
            {
                try
                {
                    var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                    string status = string.Empty;
                    var repoKai_KaizenData = new CustomBaseRepository<Kai_KaizenData>(unitOfWork);
                    var repoKai_RankMark = new CustomBaseRepository<Kai_RankMark>(unitOfWork);
                    List<Kai_KaizenData> ListKaiZendData = repoKai_KaizenData.FindBy(m => m.IsDelete != true).ToList();
                    List<Kai_RankMark> ListKaiRank = repoKai_RankMark.FindBy(m => m.IsDelete != true).ToList();

                    int Pass = 0;
                    int Fail = 0;
                    string FailCode = string.Empty;

                    foreach (var i in ListKaiZendData)
                    {
                        if (SelectIds.Any(m => m == i.ID))
                        {
                            #region Kiểm tra hợp lệ vùng điểm
                            List<Kai_RankMark> ListKaiRankByRankMark = ListKaiRank.Where(m => m.MarkIdea == i.MarkIdea).ToList();
                            if (ListKaiRankByRankMark.Any(m => m.MarkPerform == i.MarkPerform))
                            {
                                i.Status = EnumDropDown.Kai_KaizenDataStatus.E_WATTING_APPROVED.ToString();
                                Pass++;
                            }
                            else
                            {
                                Fail++;
                                FailCode += i.Hre_Profile.CodeEmp + ",";
                            }
                            #endregion
                        }
                    }
                    unitOfWork.SaveChanges();

                    return new string[] { Pass.ToString(), Fail.ToString(), FailCode };
                }
                catch
                {
                    return new string[] { "0", "0", string.Empty };
                }
            }
        }
        public Cat_OvertimeType getOTType(DateTime dateWorkDate, bool isNightShift, Hre_Profile profile, List <Cat_DayOff> list_dayOff, List <Att_RosterGroup> lstRosterGroup, List <Att_Roster> lstRosterTypeGroup)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork           = (IUnitOfWork)(new UnitOfWork(context));
                var repoAtt_LeaveDay     = new CustomBaseRepository <Att_LeaveDay>(unitOfWork);
                var repoCat_OvertimeType = new CustomBaseRepository <Cat_OvertimeType>(unitOfWork);

                Cat_OvertimeType otType = null;
                try
                {
                    dateWorkDate = dateWorkDate.Date;

                    //LamLe : Them chuc nang neu tang ca vao ngay nghi thi chon loai tang ca phu thuoc vao cau hinh Tang ca trong ngay nghi.
                    List <Att_LeaveDay> lstLeave = repoAtt_LeaveDay
                                                   .FindBy(lv => lv.IsDelete == null && lv.DateStart <= dateWorkDate && lv.DateEnd >= dateWorkDate && lv.ProfileID == profile.ID)
                                                   .ToList();
                    if (lstLeave.Count > 0)
                    {
                        Att_LeaveDay leave = lstLeave[0];
                        if (leave != null && leave.Cat_LeaveDayType != null && leave.Cat_LeaveDayType.Cat_OvertimeType != null)
                        {
                            otType = leave.Cat_LeaveDayType.Cat_OvertimeType;
                            return(otType);
                        }
                    }

                    Att_Grade grade = Att_GradeServices.GetGrade(profile, dateWorkDate);
                    if (grade == null)
                    {
                        string status = OverTimeType.E_WORKDAY.ToString();
                        otType = repoCat_OvertimeType.FindBy(dayoff => dayoff.IsDelete == null && dayoff.Code == status).FirstOrDefault();
                        return(otType);
                    }
                    list_dayOff = list_dayOff.Where(df => df.DateOff.Date == dateWorkDate.Date).ToList();
                    Cat_GradeCfg gradecfg = grade.Cat_GradeCfg;

                    //Check overtime holiday
                    //List<Cat_DayOff> list_dayOff = EntityService.Instance.GetEntityList<Cat_DayOff>(GuidContext, _userId, dayoff => dayoff.DateOff == dateWorkDate);

                    if (list_dayOff.Count > 0)
                    {
                        //Cat_GradeCfg.FieldNames.Cat_OvertimeType1
                        bool isDayOffHollyDay = false;
                        foreach (var item in list_dayOff)
                        {
                            if (item.DateOff.Date == dateWorkDate.Date && item.Type == HolidayType.E_HOLIDAY_HLD.ToString())
                            {
                                isDayOffHollyDay = true;
                            }
                        }
                        //Ca dem ngay le
                        if (isDayOffHollyDay && isNightShift)
                        {
                            otType = gradecfg.Cat_OvertimeType5;
                        }
                        //Ca dem ngay nghi cuoi tuan
                        else if (!isDayOffHollyDay && isNightShift)
                        {
                            otType = gradecfg.Cat_OvertimeType4;
                        }
                        ////Ca ngay ngay le
                        else if (isDayOffHollyDay && !isNightShift)
                        {
                            otType = gradecfg.Cat_OvertimeType2;
                        }
                        ////Ca ngay ngay nghi cuoi tuan
                        else
                        {
                            otType = gradecfg.Cat_OvertimeType1;
                        }
                    }
                    else
                    {
                        Hashtable hsRoster = Att_RosterServices.GetRosterTable(false, profile, dateWorkDate, dateWorkDate, lstRosterGroup, lstRosterTypeGroup);

                        bool isWorkday = Att_AttendanceServices.IsWorkDay(grade.Cat_GradeAttendance, hsRoster, list_dayOff, dateWorkDate);
                        if (isWorkday)
                        {
                            if (isNightShift)
                            {
                                otType = gradecfg.Cat_OvertimeType3;
                            }
                            else
                            {
                                otType = gradecfg.Cat_OvertimeType;
                            }
                            //if (gradecfg.Cat_OvertimeType == null)
                            //{

                            //    string workday = OverTimeType.E_WORKDAY.ToString();
                            //    otType = EntityService.Instance.GetEntity<Cat_OvertimeType>(GuidContext, _userId, dayoff => dayoff.Code == workday);
                            //}
                            //else
                            //    otType = gradecfg.Cat_OvertimeType;
                        }
                        else
                        {
                            if (isNightShift)
                            {
                                otType = gradecfg.Cat_OvertimeType4;
                            }
                            else
                            {
                                otType = gradecfg.Cat_OvertimeType1;
                            }
                            //if (gradecfg.Cat_OvertimeType1 == null)
                            //{
                            //    string workday = OverTimeType.E_WORKDAY.ToString();
                            //    otType = EntityService.Instance.GetEntity<Cat_OvertimeType>(GuidContext, _userId, dayoff => dayoff.Code == workday);
                            //}
                            //else
                            //    otType = gradecfg.Cat_OvertimeType1;
                        }
                    }
                }
                catch (Exception ex)
                {
                }
                return(otType);
            }
        }
        public Hashtable ComputeSalGroup(IUnitOfWork unitOfWork, DateTime monthYear, List<Sal_SalaryDepartment> lstSalDep, List<Sal_SalaryDepartmentItem> lstSalDepItem, ref List<Sal_SalaryDepartmentItem> lstItemDelete,
                                          DateTime DateStart, DateTime DateEnd)
        {
            #region Query data
            Hashtable htSalGroup = new Hashtable();
            //Nhân viên
            var reposProfile = new CustomBaseRepository<Hre_Profile>(unitOfWork);

            //Bảng công
            var reposAttendanceTb = new CustomBaseRepository<Att_AttendanceTable>(unitOfWork);

            //Bảng công chi tiết
            var reposAttendanceTbItem = new CustomBaseRepository<Att_AttendanceTableItem>(unitOfWork);

            //Chế độ lương
            var reposSalGrade = new CustomBaseRepository<Sal_Grade>(unitOfWork);
            #endregion

            foreach (Sal_SalaryDepartment salDep in lstSalDep)
            {
                List<Sal_SalaryDepartmentItem> rsDepItem = new List<Sal_SalaryDepartmentItem>();

                DateStart = salDep.DateFrom != null ? salDep.DateFrom.Value : DateStart;
                DateEnd = salDep.DateTo != null ? salDep.DateTo.Value : DateEnd;

                List<Guid> guidPro = new List<Guid>();

                //Lấy dữ liệu nhân viên
                guidPro = lstSalDepItem.Select(dt => dt.ProfileID).ToList();
                var lstProfileOrg = reposProfile.FindBy(hr => hr.IsDelete == null && guidPro.Contains(hr.ID)).ToList();

                //Lấy grade theo ds nhân viên
                var lstGradeAll = reposSalGrade.FindBy(gr => gr.IsDelete == null && guidPro.Contains(gr.ProfileID)).ToList();

                //Lấy bảng công theo ds nv
                var lstAttAtendance = reposAttendanceTb.FindBy(att => att.IsDelete == null && att.MonthYear == monthYear && guidPro.Contains(att.ProfileID)).ToList();
                var lstAttAtendanceID = lstAttAtendance.Select(att => att.ID).ToList();

                //Lấy bảng công chi tiết
                var lstAttAttendanceItem = reposAttendanceTbItem.FindBy(it => it.IsDelete == null && lstAttAtendanceID.Contains(it.AttendanceTableID)).ToList();

                foreach (Hre_Profile _pro in lstProfileOrg)
                {
                    #region Ver8 chưa dùng
                    //Sal_Grade grade = GradeDAO.GetGrade(lstGradeAll, _pro.ID, DateEnd);
                    //if (grade == null)
                    //    continue;

                    //Cat_GradeCfg gradeCfg = lstGradeCfg.Where(gra => gra.ID == grade.GradeID).FirstOrDefault();
                    //if (gradeCfg == null || gradeCfg.Formula != enumFomula)
                    //    continue;

                    //AttendanceService.GetSalaryDateRange(gradeCfg, sys_AppConfig, null, monthYear, out DateStart, out DateEnd);
                    //if (salDep.DateFrom != null && salDep.DateFrom.Value >= DateStart && salDep.DateFrom.Value <= DateEnd)
                    //{
                    //    DateStart = salDep.DateFrom.Value;
                    //}
                    //if (salDep.DateTo != null && salDep.DateTo.Value >= DateStart && salDep.DateTo.Value <= DateEnd)
                    //{
                    //    DateEnd = salDep.DateTo.Value;
                    //}
                    #endregion

                    //dữ liệu công
                    var _att = lstAttAtendance.Where(att => att.ProfileID == _pro.ID).Select(att => new { att.ID }).FirstOrDefault();
                    if (_att == null)
                        continue;
                    var _attLstItem = lstAttAttendanceItem.Where(at => at.AttendanceTableID == _att.ID).ToList();

                    //Nếu nhân viên được tính lại thì sẽ cho vào danh sách để xóa đi tính lại.
                    List<Sal_SalaryDepartmentItem> lstItemPro = lstSalDepItem.Where(it => it.ProfileID == _pro.ID && it.SalaryDepartmentID == salDep.ID).ToList();
                    lstItemDelete.AddRange(lstItemPro);

                    //Bắt đầu thêm giờ công, hệ số, giờ OT lần lượt cho từng người
                    rsDepItem.AddRange(CalSalaryItemProfile(salDep, _attLstItem, _pro, lstItemPro, DateStart, DateEnd, monthYear));
                }

                //Tính toán tiền lương và các loại tiền OT (XC Finished)
                ComputeAmountPro(rsDepItem, salDep);
                htSalGroup.Add(salDep, rsDepItem);
            }
            return htSalGroup;
        }
        public void ComputeCommission(List<Hre_ProfileEntity> listProfile, Att_CutOffDurationEntity CutOffDuration, Guid asynTaskID, string HeaderTemplateLog, string methodPayroll, Guid CutOffDuration2ID, string UserLogin)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                var repoSys_AsynTask = new CustomBaseRepository<Sys_AsynTask>(unitOfWork);
                var repoPayrollTable = new CustomBaseRepository<Sal_PayrollTable>(unitOfWork);
                var Sys_Model = repoSys_AsynTask.FindBy(m => m.ID == asynTaskID).FirstOrDefault();

                if (!DeletePayrollTable(listProfile.Select(d => d.ID).ToList(), CutOffDuration.ID))
                {
                    Sys_Model.Status = AsynTaskStatus.Error.ToString();
                    Sys_Model.Description = "Không thể xóa bảng lương cũ";
                    Sys_Model.PercentComplete = 1;
                    unitOfWork.SaveChanges();
                }
                else
                {
                    #region Get All Data

                    DateTime DatetimeStart = DateTime.Now;
                    ComputePayrollDataModel TotalData = PayrollServices.GetDataForComputeSalary(CutOffDuration,UserLogin);
                    //FileLog.WriteLog("", "Get Data", Common.ComputeTime(DatetimeStart, DateTime.Now));

                    #endregion

                    //Kiểm tra xem có lỗi store hay không
                    if (TotalData.Status != null && TotalData.Status != string.Empty)
                    {
                        Sys_Model.Status = AsynTaskStatus.Error.ToString();
                        Sys_Model.Description = TotalData.Status;
                        Sys_Model.PercentComplete = 1;
                        unitOfWork.SaveChanges();
                    }
                    else
                    {
                        #region Ghi Log
                        //Lấy đường dẫn thư mục ghi log
                        //set lại thư mục ghi log
                        //WriteLog.SettingPath = Common.GetPath("Log");
                        //WriteLog.DynamicDirectory = "ComputePayroll" + DateTime.Now.ToString("dd-MM-yyyy_HH-mm-ss");
                        //WriteLog.FileName = "LogFile";
                        //WriteLog.WriteLog(HeaderTemplateLog, "", "");
                        #endregion

                        int pageSize = 100;//mỗi lần tính cho 100 nhân viên
                        int totalProfile = listProfile.Count;//Tổng số nhâ viên

                        foreach (var listProfileBySize in listProfile.Chunk(pageSize))
                        {
                            ComputeCommission_Progress(TotalData, listProfileBySize.ToList(), CutOffDuration, Sys_Model.ID, totalProfile, methodPayroll, CutOffDuration2ID);
                        }
                    }
                }
            }
        }
        public Hashtable ComputeSalaryDepartment(DateTime monthYear, DateTime DateStart, DateTime DateEnd, List<Sal_SalaryDepartment> lstSalDep, ref Hashtable htSalGroup)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (UnitOfWork)(new UnitOfWork(context));
                Sys_AttOvertimePermitConfigServices Sys_Services = new Sys_AttOvertimePermitConfigServices();

                #region Ver8 chưa dùng
                //String enumFomula = PayrollComputeMethod.E_FORMULA.ToString();
                //var responCatGradeCfg = new CustomBaseRepository<Cat_GradeCfg>(unitOfWork);
                //var lstGradeCfg = responCatGradeCfg.GetAll().Where(gr => gr.IsDelete == null && gr.Formula == enumFomula).ToList();
                //if (lstGradeCfg.Count <= 0)
                //    return htSalGroup;
                #endregion

                if (lstSalDep == null)
                {
                    var responSalDept = new CustomBaseRepository<Sal_SalaryDepartment>(unitOfWork);
                    lstSalDep = responSalDept.FindBy(ls => ls.MonthYear == monthYear && ls.IsDelete == null).ToList();
                }
                List<Guid> lstGuidSalDep = lstSalDep.Select(sal => sal.ID).ToList();
                var responSalDeptItem = new CustomBaseRepository<Sal_SalaryDepartmentItem>(unitOfWork);
                List<Sal_SalaryDepartmentItem> lstSalDepItem = responSalDeptItem.FindBy(ls => lstGuidSalDep.Contains(ls.SalaryDepartmentID) && ls.IsDelete == null).ToList();

                //Tạo list chứa ds chi tiết lương BP đã tính trước đó => để xóa đi, update mới
                List<Sal_SalaryDepartmentItem> lstItemDelete = new List<Sal_SalaryDepartmentItem>();

                #region ver8 chưa dùng
                //lấy chu kỳ lương theo chế độ lương
                //var responAppconfig = new CustomBaseRepository<Sys_AppConfig>(unitOfWork);
                //List<Sys_AppConfig> lstappConfig = responAppconfig.GetAll().Where(ap => ap.IsDelete == null).ToList();
                //string type = AppConfig.E_RANGE_SALARY_MONTH.ToString();
                //Sys_AppConfig sys_AppConfig = lstappConfig.Where(sy => sy.Info == type).FirstOrDefault();
                //AttendanceService.GetRangeMaxMinGrade(lstGradeCfg, monthYear, out DateStart, out DateEnd);
                #endregion

                //AppConfig
                //var service = new Sys_AttOvertimePermitConfigServices();
                var value52 = Sys_Services.GetConfigValue<string>(AppConfig.HRM_SAL_CONFIG_VALUE52); ; // service.GetConfigValue<string>(AppConfig.HRM_SAL_CONFIG_VALUE52);

                /*XỬ LÝ THEO 2 OPTION */
                //sử dụng hệ số từ lương cơ bản, bổ sung NV để tính lương với nhiều trạng thái (XC 1.1)
                if (value52 == AppConfig.E_RATE_BY_BASICSALARY.ToString())
                {
                    var responOrgAll = new CustomBaseRepository<Cat_OrgStructure>(unitOfWork);
                    List<Cat_OrgStructure> listOrgAll = responOrgAll.FindBy(org => org.IsDelete == null).ToList();
                    htSalGroup = ComputeSalGroup(unitOfWork, monthYear, lstSalDep, lstSalDepItem, ref lstItemDelete, DateStart, DateEnd,  listOrgAll);
                }
                //sử dụng hệ số từ màn hình nhập hệ số, nhân viên chi tiết trong table Sal_DepartmentItem(XC 2.1)
                else
                {
                    //Chỉ sử dụng: "lstSalDepItem" để lấy danh sách nhân viên và hệ số của nhân viên
                    htSalGroup = ComputeSalGroup(unitOfWork, monthYear, lstSalDep, lstSalDepItem, ref lstItemDelete, DateStart, DateEnd);
                }
                BaseService service = new BaseService();
                service.Delete<Sal_SalaryDepartmentItem>(lstItemDelete);
                //EntityService.SaveChanges(Guid.Empty);
                unitOfWork.SaveChanges();
                return htSalGroup;
            }
        }
        public void ComputeCommission_Progress(ComputePayrollDataModel TotalData, List<Hre_ProfileEntity> ProfileID, Att_CutOffDurationEntity CutOffDuration, Guid Sys_AsynTaskID, int totalProfile, string methodPayroll, Guid CutOffDuration2ID)
        {
            using (var context = new VnrHrmDataContext())
            {
                TraceLogManager FileLog = new TraceLogManager();
                var unitOfWork = new UnitOfWork(context);

                #region Init Repo
                var repoSys_AsynTask = new CustomBaseRepository<Sys_AsynTask>(unitOfWork);
                var repoHre_profile = new CustomBaseRepository<Hre_ProfileEntity>(unitOfWork);
                var repoCat_Element = new CustomBaseRepository<Cat_ElementEntity>(unitOfWork);
                var repoSal_BasicSalary = new CustomBaseRepository<Sal_BasicSalaryEntity>(unitOfWork);
                //var repoPayrollTable = new CustomBaseRepository<Sal_PayrollTable>(unitOfWork);
                //var repoPayrollTableItem = new CustomBaseRepository<Sal_PayrollTableItem>(unitOfWork);

                var repoCat_OvertimeType = new CustomBaseRepository<Cat_OvertimeTypeEntity>(unitOfWork);
                var repoCat_LeaveDayType = new CustomBaseRepository<Cat_LeaveDayTypeEntity>(unitOfWork);
                var repoCat_UsualAllowanceEntity = new CustomBaseRepository<Cat_UsualAllowanceEntity>(unitOfWork);
                var repoCat_GradePayroll = new CustomBaseRepository<Cat_GradePayrollEntity>(unitOfWork);
                var repoCat_UnusualAllowanceCfg = new CustomBaseRepository<Cat_UnusualAllowanceCfgEntity>(unitOfWork);
                var repoSal_PayrollTable = new CustomBaseRepository<Sal_PayrollTable>(unitOfWork);
                #endregion

                //Các biến xử dụng chung
                Sys_AsynTask asynTask = new Sys_AsynTask();

                //[SCV] list lưu tiền khấu nhân viên chưa đủ thâm niên của shop
                Dictionary<Guid, ValueCount> listTmpDeduction = new Dictionary<Guid, ValueCount>();
                List<Sal_PayCommissionItem> listPayrollTableItem = new List<Sal_PayCommissionItem>();
                List<Sal_PayCommission> listPayrollTable = new List<Sal_PayCommission>();

                //Get asynTask
                asynTask = repoSys_AsynTask.FindBy(m => m.ID == Sys_AsynTaskID).FirstOrDefault();

                //Order By theo ngày vào làm để tính trường hợp nhân viên không đủ thâm niên của dự án SCV
                ProfileID = ProfileID.OrderBy(m => m.DateHire).ToList();
                ParallelOptions parallelOptions = new ParallelOptions();

                #region Duyệt Profile

                Parallel.For(0, ProfileID.Count, parallelOptions, d =>
                {
                    var profileItem = ProfileID[d];
                    bool isCancled = false;

                    //Biến tổng lưu tất cả các value của Formula
                    List<ElementFormula> listElementFormula = new List<ElementFormula>();

                    //Lấy các phần tử tính lương nằm trong Grade của nhân viên
                    Sal_GradeEntity Grade = PayrollServices.FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd);
      
                    //lấy phần tử tính lương theo grade
                    List<Cat_ElementEntity> listElement = TotalData.listElement_All.Where(m => m.GradePayrollID != null && (Guid)m.GradePayrollID == Grade.GradePayrollID && m.MethodPayroll != null && m.MethodPayroll == methodPayroll).ToList();
                   
                    if (!isCancled)
                    {
                        #region tạo mới PayrollTable
                        Sal_PayCommission PayrollTable_Model = new Sal_PayCommission()
                        {
                            ID = Guid.NewGuid(),
                            ProfileID = profileItem.ID,
                            CutoffDurationID = CutOffDuration.ID,
                            MonthYear = CutOffDuration.MonthYear,
                            CutoffDuration2ID = CutOffDuration2ID,
                            //OrgStructureID = profileItem.OrgStructureID,
                            //PositionID = profileItem.PositionID,
                            //JobTitleID = profileItem.JobTitleID,
                            //EmployeeTypeID = profileItem.EmpTypeID,
                            //PayrollGroupID = profileItem.PayrollGroupID,
                            //CostCentreID = profileItem.CostCentreID,
                            //IncomeBeforeTax = 0,
                            //DependantCount = 0,
                            //IncomeTaxable = 0,
                            //AmountPaidPITCom = 0,
                            //AmountPaidPITEmp = 0,
                            //IncomeNET = 0,
                            //BankID = profileItem.BankID,
                            //AccountNo = profileItem.AccountNo,
                        };

                        lock (listPayrollTable)
                        {
                            listPayrollTable.Add(PayrollTable_Model);
                        }

                        #endregion

                        //bắt lỗi tính công thức có giá trị nào null hay không
                        try
                        {
                            listElementFormula = PayrollServices.ParseElementFormula(listElementFormula, listElement, TotalData, profileItem, CutOffDuration, listTmpDeduction,false, FileLog);

                            listElement = listElement.OrderBy(m => m.OrderNumber).ToList();//sắp xếp lại

                            //Duyệt qua các phần tử tính lương 
                            foreach (var elementItem in listElement)
                            {
                                Sal_PayCommissionItem tableItem = new Sal_PayCommissionItem();
                                tableItem.ID = Guid.NewGuid();
                                tableItem.PayCommissionID = PayrollTable_Model.ID;
                                tableItem.Name = elementItem.ElementName;
                                tableItem.Code = elementItem.ElementCode;
                                tableItem.OrderNo = elementItem.OrderNumber != null ? (int)elementItem.OrderNumber : 0;
                                tableItem.ElementType = elementItem.TabType;
                                tableItem.ValueType = elementItem.Type;
                                tableItem.IsShow = elementItem.Invisible != null ? !elementItem.Invisible : true;
                                if (elementItem.IsBold == true)
                                {
                                    tableItem.Description += "E_BOLD,";
                                }
                                tableItem.Description += elementItem.ElementLevel + "," + elementItem.Type;
                                var ElementResult = listElementFormula.Where(m => m.VariableName.Trim() == elementItem.ElementCode.Trim()).FirstOrDefault();
                                if (ElementResult != null)
                                {
                                    tableItem.Value = ElementResult.Value.ToString();
                                    tableItem.Description = ElementResult.ErrorMessage;
                                }
                                else
                                {
                                    tableItem.Value = "0";
                                    tableItem.Description = "Không Tìm Thấy Phần Tử !";
                                }

                                lock (listPayrollTableItem)
                                {
                                    listPayrollTableItem.Add(tableItem);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Sal_PayCommissionItem tableItem = new Sal_PayCommissionItem();
                            tableItem.ID = Guid.NewGuid();
                            tableItem.PayCommissionID = PayrollTable_Model.ID;
                            tableItem.Name = "Lỗi, không thể tính được phần tử " + ex.Message;
                            tableItem.Code = "Error";
                            tableItem.OrderNo = 0;
                            tableItem.ElementType = "Payroll";
                            tableItem.ValueType = "Double";
                            tableItem.Value = "0";
                            tableItem.Description = ex.Message;

                            lock (listPayrollTableItem)
                            {
                                listPayrollTableItem.Add(tableItem);
                            }
                        }
                    }
                });

                #endregion

                asynTask = repoSys_AsynTask.FindBy(m => m.ID == Sys_AsynTaskID).FirstOrDefault();
                asynTask.PercentComplete += ((double)ProfileID.Count / (double)totalProfile);
                asynTask.Description = FileLog.GetFullPath(FileLog.FileName);
                asynTask.TimeEnd = DateTime.Now;

                if (asynTask.PercentComplete >= 1)
                {
                    asynTask.Status = AsynTaskStatus.Done.ToString();
                    asynTask.PercentComplete = 1D;
                }

                var connection = context.Database.Connection.GetAdoConnection();

                using (DbCommander commander = new DbCommander(connection))
                {
                    if (connection.IsSqlConnection())
                    {
                        var bulkCopyHelper = new SqlBulkCopyHelper(connection.ConnectionString);
                        var dtPayrollTable = commander.GetSchema("Columns", new string[] { null, null, typeof(Sal_PayCommission).Name });
                        var dtPayrollTableItem = commander.GetSchema("Columns", new string[] { null, null, typeof(Sal_PayCommissionItem).Name });
                        var payrollTableFields = dtPayrollTable.Rows.OfType<System.Data.DataRow>().Select(d => d["Column_Name"].GetString()).ToArray();
                        var payrollTableItemFields = dtPayrollTableItem.Rows.OfType<System.Data.DataRow>().Select(d => d["Column_Name"].GetString()).ToArray();
                        bulkCopyHelper.WriteToServer(listPayrollTable, typeof(Sal_PayCommission).Name, payrollTableFields);

                        foreach (var listPayrollTableItemBySize in listPayrollTableItem.Chunk(2000))
                        {
                            bulkCopyHelper.WriteToServer(listPayrollTableItemBySize.ToList(),
                                typeof(Sal_PayCommissionItem).Name, payrollTableItemFields);
                        }
                    }
                    else
                    {
                        var dtPayrollTable = commander.GetSchema("Columns", new string[] { null, typeof(Sal_PayCommission).Name });
                        var dtPayrollTableItem = commander.GetSchema("Columns", new string[] { null, typeof(Sal_PayCommissionItem).Name });
                        var payrollTableFields = dtPayrollTable.Rows.OfType<System.Data.DataRow>().Select(d => d["Name"].GetString()).ToArray();
                        var payrollTableItemFields = dtPayrollTableItem.Rows.OfType<System.Data.DataRow>().Select(d => d["Name"].GetString()).ToArray();

                        commander.InsertList(typeof(Sal_PayCommission).Name, listPayrollTable, payrollTableFields);

                        foreach (var listPayrollTableItemBySize in listPayrollTableItem.Chunk(2000))
                        {
                            commander.InsertList(typeof(Sal_PayCommissionItem).Name, listPayrollTableItemBySize.ToList(), payrollTableItemFields);
                        }
                    }
                }

                //repoPayrollTableItem.Add(listPayrollTableItem);
                //repoPayrollTable.Add(listPayrollTable);
                unitOfWork.SaveChanges();
            }
        }
        /// <summary>
        /// Button Tính Phép Bệnh
        /// </summary>
        /// <param name="Year"></param>
        /// <param name="orgStructure"></param>
        /// <param name="LstProfileStatus"></param>
        /// <returns></returns>
        public bool ComputeAnnualSickLeaveDetail(int Year, string orgStructure, string LstProfileStatus, string UserLogin)
        {
            var result = false;
            using (var context = new VnrHrmDataContext())
            {
                string status = string.Empty;
                var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                var repoAtt_AnnualLeaveDetail = new CustomBaseRepository<Att_AnnualLeaveDetail>(unitOfWork);
                var repoHre_Profile = new CustomBaseRepository<Hre_Profile>(unitOfWork);
                var repoHre_HDTJob = new CustomBaseRepository<Hre_HDTJob>(unitOfWork);
                var repoCat_DayOff = new CustomBaseRepository<Cat_DayOff>(unitOfWork);
                var repoCat_LeaveDayType = new CustomBaseRepository<Cat_LeaveDayType>(unitOfWork);
                var repoAtt_LeaveDay = new CustomBaseRepository<Att_LeaveDay>(unitOfWork);
                var repoCat_JobTitle = new CustomBaseRepository<Cat_JobTitle>(unitOfWork);


                #region FilterInfo
                string E_SICK_LEAVE = AnnualLeaveDetailType.E_SICK_LEAVE.ToString();

                Att_AnnualLeaveDetail AnnualLeaveDetailTop = repoAtt_AnnualLeaveDetail
                    .FindBy(m => m.IsDelete == null && m.Type == E_SICK_LEAVE && m.Year == Year).FirstOrDefault();

                DateTime beginyear = (AnnualLeaveDetailTop == null || AnnualLeaveDetailTop.MonthStart == null) ? new DateTime(Year, 1, 1) : AnnualLeaveDetailTop.MonthStart.Value;
                DateTime endYear = beginyear.AddYears(1).AddMinutes(-1);

                List<object> lstObj = new List<object>();
                lstObj.Add(orgStructure);
                lstObj.Add(null);
                lstObj.Add(null);
                var lstProfileQuery = GetData<Hre_ProfileEntity>(lstObj, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, UserLogin, ref status).ToList();

                if (LstProfileStatus != null)
                {
                    if (LstProfileStatus == StatusEmpLeaveDetail.E_NEWEMPINYEAR.ToString())
                    {
                        lstProfileQuery = lstProfileQuery.Where(m => m.DateHire != null && m.DateHire >= beginyear && m.DateHire <= endYear).ToList();
                    }
                    if (LstProfileStatus == StatusEmpLeaveDetail.E_RESIGNEMPINYEAR.ToString())
                    {
                        lstProfileQuery = lstProfileQuery.Where(m => m.DateQuit != null && m.DateQuit >= beginyear && m.DateQuit <= endYear).ToList();
                    }
                    if (LstProfileStatus == StatusEmpLeaveDetail.E_EMPOFHDT4.ToString())
                    {
                        string Job4 = HDTJobType.E_Four.ToString();
                        List<Guid> lstprofileHDT4 = repoHre_HDTJob
                            .FindBy(m => m.IsDelete == null && m.Type == Job4 && m.DateFrom <= endYear && m.DateTo >= beginyear && m.ProfileID != null)
                            .Select(m => m.ProfileID.Value).ToList<Guid>();
                        lstProfileQuery = lstProfileQuery.Where(m => lstprofileHDT4.Contains(m.ID)).ToList();
                    }
                    if (LstProfileStatus == StatusEmpLeaveDetail.E_EMPOFHDT5.ToString())
                    {
                        string Job5 = HDTJobType.E_Five.ToString();
                        List<Guid> lstprofileHDT5 = repoHre_HDTJob
                            .FindBy(m => m.IsDelete == null && m.Type == Job5 && m.DateFrom <= endYear && m.DateTo >= beginyear && m.ProfileID != null)
                            .Select(m => m.ProfileID.Value).ToList<Guid>();
                        lstProfileQuery = lstProfileQuery.Where(m => lstprofileHDT5.Contains(m.ID)).ToList();
                    }
                }

                List<Guid> lstProfileID = lstProfileQuery.Select(m => m.ID).Distinct().ToList<Guid>();
                #endregion
                #region get Data
                //string E_STANDARD_WORKDAY = AppConfig.E_STANDARD_WORKDAY.ToString();
                //Sys_AppConfig appconfig = EntityService.CreateQueryable<Sys_AppConfig>(false, GuidContext, Guid.Empty, m => m.Info == E_STANDARD_WORKDAY).FirstOrDefault();
                //if (appconfig == null || string.IsNullOrEmpty(appconfig.Value76) || string.IsNullOrEmpty(appconfig.Value77))
                //{
                //    Common.MessageBoxs(Messages.Msg, Messages.PleaseConfigSickLeaveAtTotalConfig, MessageBox.Icon.WARNING, string.Empty);
                //    return;
                //}

                string HRM_ATT_ANNUALSICKLEAVE_ = AppConfig.HRM_ATT_ANNUALSICKLEAVE_.ToString();
                List<object> lstO = new List<object>();
                lstO.Add(HRM_ATT_ANNUALSICKLEAVE_);
                lstO.Add(null);
                lstO.Add(null);
                var config = GetData<Sys_AllSettingEntity>(lstO, ConstantSql.hrm_sys_sp_get_AllSetting, UserLogin, ref status);

                var formular1 = config.Where(s => s.Name == AppConfig.HRM_ATT_ANNUALSICKLEAVE_FORMULARCONFIG.ToString()).FirstOrDefault();
                var formular2 = config.Where(s => s.Name == AppConfig.HRM_ATT_ANNUALSICKLEAVE_FORMULARCOMPUTE.ToString()).FirstOrDefault();

                if (config == null || string.IsNullOrEmpty(formular1.Value1) || string.IsNullOrEmpty(formular2.Value1))
                {
                    //Common.MessageBoxs(Messages.Msg, Messages.PleaseConfigAnnualLeaveAtTotalConfig, MessageBox.Icon.WARNING, string.Empty);
                    return result;
                }

                string formularConfig = formular1.Value1;
                string formularCompute = formular2.Value1;

                ParamGetConfigANL configAnl = new ParamGetConfigANL();
                (new Att_AttendanceServices()).GetConfigANL(formularConfig, out configAnl);

                int MonthBegin = 1;
                List<string> lstCodeLeaveTypeNonAnl = new List<string>();
                if (configAnl != null && configAnl.monthBeginYear != null)
                {
                    MonthBegin = configAnl.monthBeginYear;
                }
                if (configAnl != null && configAnl.lstCodeLeaveNonANL != null)
                {
                    lstCodeLeaveTypeNonAnl = configAnl.lstCodeLeaveNonANL;
                }
                DateTime BeginYear = new DateTime(Year, MonthBegin, 1);
                DateTime EndYear = BeginYear.AddYears(1).AddMinutes(-1);

                string E_APPROVED = LeaveDayStatus.E_APPROVED.ToString();
                List<DateTime> lstDayOff = repoCat_DayOff
                    .FindBy(m => m.IsDelete == null && m.DateOff > BeginYear && m.DateOff <= EndYear)
                    .Select(m => m.DateOff).Distinct().ToList<DateTime>();
                List<Hre_ProfileEntity> lstprofile = lstProfileQuery
                    .Where(m => m.DateQuit == null || (m.DateQuit != null && m.DateQuit > BeginYear))
                    .ToList<Hre_ProfileEntity>();
                List<Guid> lstLeavedayTypeNonAnl = repoCat_LeaveDayType
                    .FindBy(m => m.IsDelete == null && lstCodeLeaveTypeNonAnl.Contains(m.Code)).Select(m => m.ID).ToList<Guid>();
                List<Att_LeaveDay> lstleavedayNonANl = repoAtt_LeaveDay
                    .FindBy(m => m.IsDelete == null && m.Status == E_APPROVED && lstLeavedayTypeNonAnl.Contains(m.LeaveDayTypeID)
                        && lstProfileID.Contains(m.ProfileID)).ToList<Att_LeaveDay>();
                List<Att_LeaveDay> lstleavedayNonANlInYear = lstleavedayNonANl.Where(m => m.DateStart <= EndYear && m.DateEnd >= BeginYear).ToList<Att_LeaveDay>();
                List<Hre_HDTJob> lstHDTJob = repoHre_HDTJob
                    .FindBy(m => m.IsDelete == null && m.ProfileID != null && lstProfileID.Contains(m.ProfileID.Value)).ToList<Hre_HDTJob>();
                List<Cat_JobTitle> lstJobtitle = repoCat_JobTitle.FindBy(s => s.IsDelete == null).ToList();
                #endregion

                List<Att_AnnualLeaveDetail> lstAnnualDetail = new List<Att_AnnualLeaveDetail>();
                foreach (var item in lstprofile)
                {
                    List<Att_LeaveDay> lstLeavedayNonAnlByProfile = lstleavedayNonANl.Where(m => m.ProfileID == item.ID).ToList();
                    List<Att_LeaveDay> lstLeavedayNonAnlByProfileInYear = lstleavedayNonANlInYear.Where(m => m.ProfileID == item.ID).ToList();
                    List<Hre_HDTJob> lstHDTJobByProfile = lstHDTJob.Where(m => m.ProfileID == item.ID).ToList();
                    double AvailabelInYear = (new Att_AttendanceServices()).GetAnnualLeaveAvailableAllYear(Year, null, item.DateHire,
                        item.DateEndProbation, item.DateQuit, formularConfig,
                        formularCompute, lstLeavedayNonAnlByProfileInYear, lstJobtitle, lstDayOff, lstHDTJobByProfile, lstLeavedayNonAnlByProfile);
                    Att_AnnualLeaveDetail annualProfile = new Att_AnnualLeaveDetail();
                    annualProfile.ID = Guid.NewGuid();
                    annualProfile.ProfileID = item.ID;
                    annualProfile.MonthStart = BeginYear;
                    annualProfile.MonthEnd = EndYear;
                    annualProfile.Year = Year;
                    annualProfile.Type = E_SICK_LEAVE;
                    annualProfile.Month1 = AvailabelInYear;
                    annualProfile.Month2 = AvailabelInYear;
                    annualProfile.Month3 = AvailabelInYear;
                    annualProfile.Month4 = AvailabelInYear;
                    annualProfile.Month5 = AvailabelInYear;
                    annualProfile.Month6 = AvailabelInYear;
                    annualProfile.Month7 = AvailabelInYear;
                    annualProfile.Month8 = AvailabelInYear;
                    annualProfile.Month9 = AvailabelInYear;
                    annualProfile.Month10 = AvailabelInYear;
                    annualProfile.Month11 = AvailabelInYear;
                    annualProfile.Month12 = AvailabelInYear;
                    lstAnnualDetail.Add(annualProfile);
                }

                DataErrorCode DataErr = DataErrorCode.Unknown;

                if (lstAnnualDetail.Count > 0)
                {
                    #region lấy dữ liệu dưới DB xóa đi
                    List<Guid> lstProfileID_InDB = lstAnnualDetail.Where(m => m.ProfileID != null).Select(m => m.ProfileID.Value).ToList();


                    List<Att_AnnualLeaveDetail> lstAnnualLeaveDetail_InDB = repoAtt_AnnualLeaveDetail
                        .FindBy(m => m.IsDelete == null && m.Year == Year && m.Type == E_SICK_LEAVE && m.ProfileID != null && lstProfileID_InDB.Contains(m.ProfileID.Value)).ToList<Att_AnnualLeaveDetail>();
                    foreach (var item in lstAnnualLeaveDetail_InDB)
                    {
                        item.IsDelete = true;
                    }
                    #endregion

                    repoAtt_AnnualLeaveDetail.Add(lstAnnualDetail);
                    try
                    {
                        repoAtt_AnnualLeaveDetail.SaveChanges();
                    }
                    catch (Exception)
                    {
                        return false;
                    }

                    //EntityService.AddEntity<Att_AnnualLeaveDetail>(GuidContext, lstAnnualDetail.ToArray());
                    //DataErr = EntityService.SubmitChanges(GuidContext, LoginUserID);

                    //if (DataErr == DataErrorCode.Success)
                    //{
                    //    Common.MessageBoxs(Messages.Msg, Messages.SaveSuccess, MessageBox.Icon.INFO, string.Empty);
                    //}
                    //else
                    //{
                    //    Common.MessageBoxs(Messages.Msg, Messages.SaveUnSuccess, MessageBox.Icon.INFO, string.Empty);
                    //}
                }
                //else
                //{
                //    Common.MessageBoxs(Messages.Msg, Messages.NoDataToCompute, MessageBox.Icon.WARNING, string.Empty);
                //}
                result = true;
            }
            return result;
        }
Beispiel #58
0
        public void ComputePayroll(List<Hre_ProfileEntity> listProfile, Att_CutOffDurationEntity CutOffDuration, Guid asynTaskID, string HeaderTemplateLog, string UserLogin, bool Settlement = false)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                var repoSys_AsynTask = new CustomBaseRepository<Sys_AsynTask>(unitOfWork);
                var repoPayrollTable = new CustomBaseRepository<Sal_PayrollTable>(unitOfWork);
                var Sys_Model = repoSys_AsynTask.FindBy(m => m.ID == asynTaskID).FirstOrDefault();

                #region Ghi Log
                TraceLogManager FileLog = new TraceLogManager();
                //Lấy đường dẫn thư mục ghi log
                //set lại thư mục ghi log
                FileLog.SettingPath = Common.GetPath("Log");
                FileLog.DynamicDirectory = "ComputePayroll" + DateTime.Now.ToString("ddMMyyyy-HHmmss");
                FileLog.FileName = "LogFile";
                FileLog.WriteLog(HeaderTemplateLog, "", "");
                #endregion

                if (!DeletePayrollTable(listProfile.Select(d => d.ID).ToList(), CutOffDuration.ID, Settlement, FileLog))
                {
                    Sys_Model.Status = AsynTaskStatus.Error.ToString();
                    Sys_Model.Description = "Không thể xóa bảng lương cũ";
                    Sys_Model.PercentComplete = 1;
                    unitOfWork.SaveChanges();
                }
                else
                {
                    #region Get All Data

                    DateTime DatetimeStart = DateTime.Now;
                    ComputePayrollDataModel TotalData = GetDataForComputeSalary(CutOffDuration, UserLogin);
                    FileLog.WriteLog("", "Get All Data", Common.ComputeTime(DatetimeStart, DateTime.Now));

                    #endregion

                    //Kiểm tra xem có lỗi store hay không
                    if (TotalData.Status != null && TotalData.Status != string.Empty)
                    {
                        Sys_Model.Status = AsynTaskStatus.Error.ToString();
                        Sys_Model.Description = TotalData.Status;
                        Sys_Model.PercentComplete = 1;
                        FileLog.WriteLog("", "Store Error " + TotalData.Status);
                        unitOfWork.SaveChanges();
                    }
                    else
                    {
                        int pageSize = 100;//mỗi lần tính cho 100 nhân viên
                        int totalProfile = listProfile.Count;//Tổng số nhâ viên

                        Sys_AttOvertimePermitConfigServices ConfigServices = new Sys_AttOvertimePermitConfigServices();
                        bool ComputeOrderNumber = ConfigServices.GetConfigValue<bool>(AppConfig.HRM_SAL_COMPUTEPAYROLL_ORDERNUMBER);

                        foreach (var listProfileBySize in listProfile.Chunk(pageSize))
                        {
                            ComputePayroll_Progress(TotalData, listProfileBySize.ToList(), CutOffDuration, Sys_Model.ID, totalProfile, FileLog, ComputeOrderNumber, Settlement);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Button Tính Phép Bệnh (Cơ Chế Mới)
        /// Lưu vào Att_AnnualDetail
        /// </summary>
        /// <param name="Year"></param>
        /// <param name="orgStructure"></param>
        /// <param name="LstProfileStatus"></param>
        /// <returns></returns>
        public bool ComputeAnnualSick(int Year, string orgStructure, string LstProfileStatus, bool isFullEmp, string UserLogin)
        {
            var result = false;
            using (var context = new VnrHrmDataContext())
            {
                string status = string.Empty;
                var unitOfWork = (IUnitOfWork)new UnitOfWork(context);
                var repoCat_GradeAttendance = new CustomBaseRepository<Cat_GradeAttendance>(unitOfWork);
                var repoCat_DayOff = new CustomBaseRepository<Cat_DayOff>(unitOfWork);
                var repoCat_Shift = new CustomBaseRepository<Cat_Shift>(unitOfWork);
                var repoAtt_AnnualDetail = new CustomBaseRepository<Att_AnnualDetail>(unitOfWork);
                var repoAtt_RosterGroup = new CustomBaseRepository<Att_RosterGroup>(unitOfWork);
                var repoAtt_AnnualLeave = new CustomBaseRepository<Att_AnnualLeave>(unitOfWork);
                var repoAtt_Grade = new CustomBaseRepository<Att_Grade>(unitOfWork);
                var repoSys_AllSetting = new CustomBaseRepository<Sys_AllSetting>(unitOfWork);

                List<Guid> lstLeaveDayApproveIDs = new List<Guid>();
                List<Guid> lstLeaveDayRejectIDs = new List<Guid>();
                var shifts = repoCat_Shift.FindBy(s => s.IsDelete == null).ToList();

                List<object> lstObj = new List<object>();
                lstObj.Add(orgStructure);
                lstObj.Add(null);
                lstObj.Add(null);
                var lstProfile = GetData<Hre_ProfileEntity>(lstObj, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, UserLogin, ref status);

                List<Att_AnnualDetail> lstResult = new List<Att_AnnualDetail>();
                List<Guid> lstProfileID = lstProfile.Select(m => m.ID).ToList();
                int BeginMonth = MonthStartAnl;
                DateTime BeginYear = new DateTime(Year, BeginMonth, 1);
                DateTime EndYear = BeginYear.AddYears(1).AddMinutes(-1);
                DateTime BeginYearToGetData = BeginYear.AddMonths(-1); //trừ một tháng để lấy data (bao những data thuộc những ngày trước tháng dành cho chế độ lương ko phải từ ngày 1)

                var lstGradeCgf = repoCat_GradeAttendance.FindBy(s => s.ID != null).ToList();
                string E_APPROVED = LeaveDayStatus.E_APPROVED.ToString();

                var lstAnnualDetailInDB = new List<Att_AnnualDetail>();
                var lstLeaveDaySick = new List<Att_LeaveDay>();
                var lstAttGrade = new List<Att_Grade>();
                var lstAnualLeaveCfg = new List<Att_AnnualLeave>();
                var lstWorkingHistory = new List<Hre_WorkHistory>();
                var lstRoster = new List<Att_Roster>();

                #region Lấy Dữ Liệu
                List<object> lst2Param = new List<object>();
                lst2Param.Add(null);
                lst2Param.Add(EndYear);

                List<object> lst3Param = new List<object>();
                lst3Param.Add(null);
                lst3Param.Add(null);
                lst3Param.Add(null);

                List<object> lst4Param = new List<object>();
                lst4Param.Add(null);
                lst4Param.Add(BeginYearToGetData);
                lst4Param.Add(EndYear);
                lst4Param.Add(E_APPROVED);

                var dataAtt_LeaveDay = GetData<Att_LeaveDay>(lst3Param, ConstantSql.hrm_att_getdata_LeaveDay_Inner, UserLogin, ref status).ToList();
                var dataHre_WorkHistory = GetData<Hre_WorkHistory>(lst2Param, ConstantSql.hrm_hre_getdata_WorkHistory, UserLogin, ref status).ToList();
                var dataAtt_Roster_Inner = GetData<Att_Roster>(lst4Param, ConstantSql.hrm_att_getdata_Roster_Inner, UserLogin, ref status).ToList();
                #endregion

                if (isFullEmp != null && isFullEmp == true)
                {
                    lstAnnualDetailInDB = repoAtt_AnnualDetail.FindBy(m => m.IsDelete == null && m.ProfileID != null && m.Year == Year).ToList<Att_AnnualDetail>();
                    lstLeaveDaySick = dataAtt_LeaveDay
                                        .Where(m => m.Status == E_APPROVED && m.DateStart <= EndYear && m.DateEnd >= BeginYearToGetData && m.Cat_LeaveDayType != null && m.Cat_LeaveDayType.Code == LeavedayTypeCode.SICK.ToString() && lstProfileID.Contains(m.ProfileID)).ToList<Att_LeaveDay>();
                    lstAttGrade = repoAtt_Grade.FindBy(m => m.IsDelete == null).ToList();
                    lstAnualLeaveCfg = repoAtt_AnnualLeave.FindBy(m => m.IsDelete == null && m.Year == Year).ToList<Att_AnnualLeave>();
                    lstWorkingHistory = dataHre_WorkHistory.Where(m => m.DateEffective <= EndYear).OrderByDescending(m => m.DateEffective).ToList();
                    lstRoster = dataAtt_Roster_Inner.Where(m => m.Status == E_APPROVED && m.DateStart <= EndYear && m.DateEnd >= BeginYearToGetData).ToList<Att_Roster>();
                }
                else
                {
                    lstAnnualDetailInDB = repoAtt_AnnualDetail.FindBy(m => m.IsDelete == null && m.ProfileID != null && lstProfileID.Contains(m.ProfileID.Value) && m.Year == Year).ToList<Att_AnnualDetail>();
                    lstLeaveDaySick = dataAtt_LeaveDay
                                        .Where(m => m.Status == E_APPROVED && m.DateStart <= EndYear && m.DateEnd >= BeginYearToGetData && m.Cat_LeaveDayType != null && m.Cat_LeaveDayType.Code == LeavedayTypeCode.SICK.ToString() && lstProfileID.Contains(m.ProfileID)).ToList<Att_LeaveDay>();
                    lstAttGrade = repoAtt_Grade.FindBy(m => m.IsDelete == null && lstProfileID.Contains(m.ProfileID.Value)).ToList<Att_Grade>();
                    lstAnualLeaveCfg = repoAtt_AnnualLeave.FindBy(m => m.IsDelete == null && m.Year == Year && lstProfileID.Contains(m.ProfileID)).ToList<Att_AnnualLeave>();
                    lstWorkingHistory = dataHre_WorkHistory.Where(m => m.DateEffective <= EndYear && lstProfileID.Contains(m.ProfileID)).OrderByDescending(m => m.DateEffective).ToList<Hre_WorkHistory>();
                    lstRoster = dataAtt_Roster_Inner.Where(m => m.Status == E_APPROVED && m.DateStart <= EndYear && m.DateEnd >= BeginYearToGetData && lstProfileID.Contains(m.ProfileID)).ToList<Att_Roster>();
                }

                if (lstLeaveDayApproveIDs != null && lstLeaveDayApproveIDs.Count > 0)
                {
                    lstLeaveDaySick.AddRange(dataAtt_LeaveDay.Where(m => lstLeaveDayApproveIDs.Contains(m.ID)).ToList<Att_LeaveDay>());
                    lstLeaveDaySick = lstLeaveDaySick.Distinct().ToList();
                }
                if (lstLeaveDayRejectIDs != null && lstLeaveDayRejectIDs.Count > 0)
                {
                    lstLeaveDaySick = lstLeaveDaySick.Where(m => !lstLeaveDayRejectIDs.Contains(m.ID)).ToList();
                }
                var lstRosterGroup = repoAtt_RosterGroup.FindBy(m => m.IsDelete == null && m.DateStart <= EndYear && m.DateEnd >= BeginYearToGetData).ToList<Att_RosterGroup>();
                var lstDayOff = repoCat_DayOff.FindBy(m => m.IsDelete == null && m.DateOff >= BeginYearToGetData && m.DateOff <= EndYear).ToList<Cat_DayOff>();

                // Phép Năm chốt Từ Ngày 1 -> 31 Hàng Tháng 
                bool IsFrom1To31 = false;
                string type2 = AppConfig.HRM_ATT_ANNUALLEAVE_ANNUALBEGINMONTHTOENDMONTH.ToString();
                Sys_AllSetting sys_ANNUAL_BEGINMONTHTO_ENDMONTH = repoSys_AllSetting.FindBy(sy => sy.IsDelete == null && sy.Name == type2).FirstOrDefault();
                if (sys_ANNUAL_BEGINMONTHTO_ENDMONTH != null && sys_ANNUAL_BEGINMONTHTO_ENDMONTH.Value1 == bool.TrueString)
                {
                    IsFrom1To31 = true;
                }

                foreach (var profile in lstProfile)
                {
                    var lstGradeByProfile = lstAttGrade.Where(m => m.ProfileID == profile.ID).OrderByDescending(m => m.MonthStart).ToList();
                    var lstLeaveDaySickByprofile = lstLeaveDaySick.Where(m => m.ProfileID == profile.ID).ToList();
                    var AnualLeaveCfg = lstAnualLeaveCfg.Where(m => m.ProfileID == profile.ID).FirstOrDefault();
                    var lstRosterByProfile = lstRoster.Where(m => m.ProfileID == profile.ID).ToList();
                    var lstWorkHistoryByProfile = lstWorkingHistory.Where(m => m.ProfileID == profile.ID).ToList();

                    List<Att_AnnualDetail> lstAnnualDetailByProfile = AnalyzeAnnualSickPerProfile(profile, lstGradeCgf, lstGradeByProfile,
                        BeginYear, EndYear, lstLeaveDaySickByprofile, lstAnnualDetailInDB, AnualLeaveCfg, lstRosterByProfile,
                        lstRosterGroup, lstWorkHistoryByProfile, lstDayOff, IsFrom1To31, shifts);

                    //lstResult.AddRange(lstAnnualDetailByProfile);
                    repoAtt_AnnualDetail.Add(lstAnnualDetailByProfile);
                }
                repoAtt_AnnualDetail.SaveChanges();


                //DataErrorCode DataErr = DataErrorCode.Unknown;
                //if (lstAnnualDetail.Count > 0)
                //{
                //    #region lấy dữ liệu dưới DB xóa đi
                //    List<Guid> lstProfileID_InDB = lstAnnualDetail.Where(m => m.ProfileID != null).Select(m => m.ProfileID.Value).ToList();


                //    List<Att_AnnualDetail> lstAnnualLeaveDetail_InDB = repoAtt_AnnualDetail
                //        .FindBy(m => m.IsDelete == null && m.Year == Year && m.Type == E_SICK_LEAVE && m.ProfileID != null && lstProfileID_InDB.Contains(m.ProfileID.Value)).ToList<Att_AnnualDetail>();
                //    foreach (var item in lstAnnualLeaveDetail_InDB)
                //    {
                //        item.IsDelete = true;
                //    }
                //    #endregion

                //    repoAtt_AnnualDetail.Add(lstAnnualDetail);
                //    try
                //    {
                //        repoAtt_AnnualDetail.SaveChanges();
                //    }
                //    catch (Exception)
                //    {
                //        return false;
                //    }
                //}
                result = true;
            }
            return result;
        }
        /// <summary>
        /// Edit comment Trung.le 20120529
        /// Them thuoc tinh Khong cat Overtime qua ngày E_STANDARD_WORKDAY - Value37 Trung.le 20120529
        /// </summary>
        /// <param name="overtime"></param>
        /// <param name="lstDayOff"></param>
        /// <param name="_LstPregnancy"></param>
        /// <param name="GuidContext"></param>
        /// <param name="_userId"></param>
        /// <param name="isByShift">Lấy theo ca làm việc của từng người</param>
        /// <returns></returns>
        public List <Att_OvertimeEntity> AnalysisOvertime(Att_OvertimeEntity overtime, List <Cat_DayOff> lstDayOff,
                                                          List <Att_Pregnancy> _LstPregnancy, bool isByShift, bool isAllowCutBreakHour, string UserLogin)
        {
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork    = (IUnitOfWork)(new UnitOfWork(context));
                var repoCat_Shift = new CustomBaseRepository <Cat_Shift>(unitOfWork);

                Cat_Shift ShiftOfOT = repoCat_Shift.FindBy(s => s.ID == overtime.ShiftID).FirstOrDefault();


                string status = string.Empty;

                Att_OvertimeEntity baseOT = null;
                if (overtime != null)
                {
                    //overtime.SerialCode = overtime.Workdate.ToString("ddMMyyyy");
                }

                List <Att_OvertimeEntity> listOvertimeInsert = new List <Att_OvertimeEntity>();
                Hre_Profile profile = new Hre_Profile();
                profile.ID = overtime.ProfileID;
                DateTime _workDate    = overtime.WorkDate;
                DateTime dateWorkDate = _workDate;

                string        key      = "HRM_ATT_OT";
                List <object> lstSysOT = new List <object>();
                lstSysOT.Add(key);
                lstSysOT.Add(null);
                lstSysOT.Add(null);
                var config = GetData <Sys_AllSettingEntity>(lstSysOT, ConstantSql.hrm_sys_sp_get_AllSetting, UserLogin, ref status);
                if (config == null)
                {
                    return(listOvertimeInsert);
                }
                var  NoCutOvertimePassDay   = config.Where(s => s.Name == AppConfig.HRM_ATT_OT_NOCUTOVERTIMEPASSDAY.ToString()).FirstOrDefault();
                var  ByPeriodOfTime         = config.Where(s => s.Name == AppConfig.HRM_ATT_OT_BYPERIODOFTIME.ToString()).FirstOrDefault();
                var  nightShiftFrom         = config.Where(s => s.Name == AppConfig.HRM_ATT_OT_NIGHTSHIFTFROM.ToString()).FirstOrDefault();
                var  nightShiftTo           = config.Where(s => s.Name == AppConfig.HRM_ATT_OT_NIGHTSHIFTTO.ToString()).FirstOrDefault();
                bool isNocutOvertimePassDay = Convert.ToBoolean(NoCutOvertimePassDay.Value1);//Không cắt Overtime qua ngày


                List <Hre_Profile> lstProfile = new List <Hre_Profile>()
                {
                    profile
                };
                List <Guid>            lstProfileIDs      = lstProfile.Select(m => m.ID).ToList();
                List <Att_Roster>      lstRosterTypeGroup = new List <Att_Roster>();
                List <Att_RosterGroup> lstRosterGroup     = new List <Att_RosterGroup>();
                Att_RosterServices.GetRosterGroup(lstProfileIDs, _workDate.Date, _workDate.Date, out lstRosterTypeGroup, out lstRosterGroup);

                string registryCode  = "OT_" + overtime.CodeEmp + "_" + overtime.WorkDate.ToString("ddMMyyyyHHmmss");
                double basicHours    = overtime.RegisterHours;
                double durationHours = overtime.RegisterHours;
                //overtime.BasicHours = basicHours;
                //overtime.RegisterCode = registryCode;
                bool                isWorkDay       = true;
                DateTime            dateWorkDateEnd = dateWorkDate.AddHours(durationHours);
                Att_Grade           grade           = Att_GradeServices.GetGrade(profile, _workDate.Date);
                Cat_GradeAttendance gradeCfg        = grade == null ? null : grade.Cat_GradeAttendance;
                if (gradeCfg == null)
                {
                    return(listOvertimeInsert);
                }
                Hashtable htable = null;
                htable    = Att_RosterServices.GetRosterTable(false, profile, _workDate.Date, _workDate.Date, lstRosterGroup, lstRosterTypeGroup);
                isWorkDay = Att_AttendanceServices.IsWorkDay(gradeCfg, htable, lstDayOff, _workDate.Date);
                if (isByShift)//Lấy theo ca làm việc của từng người
                {
                    #region Lấy theo ca làm việc của từng người

                    Cat_Shift ship = Att_AttendanceServices.GetShift(gradeCfg, htable, _workDate.Date);
                    if (ship != null)
                    {
                        if (isWorkDay)
                        {
                            if (overtime.DurationType == EnumDropDown.OvertimeDurationType.E_OT_LATE.ToString() && ship != null)
                            {
                                DateTime timeOut = ship.InTime.AddHours(ship.CoOut);
                                dateWorkDate    = _workDate.Date.AddHours(timeOut.Hour).AddMinutes(timeOut.Minute);
                                dateWorkDateEnd = dateWorkDate.AddHours(durationHours);
                            }
                            else if (overtime.DurationType == EnumDropDown.OvertimeDurationType.E_OT_EARLY.ToString() && ship != null)
                            {
                                DateTime timeIn = ship.InTime;
                                dateWorkDate    = _workDate.Date.AddHours(timeIn.Hour).AddMinutes(timeIn.Minute);
                                dateWorkDateEnd = dateWorkDate;
                                dateWorkDate    = dateWorkDate.AddHours(-durationHours);
                            }
                        }
                        else
                        {
                            DateTime timeIn = ship.InTime;
                            dateWorkDate = _workDate.Date.AddHours(timeIn.Hour).AddMinutes(timeIn.Minute);
                        }
                    }
                    else
                    {
                        dateWorkDate    = dateWorkDate.Date;
                        dateWorkDateEnd = dateWorkDate.AddHours(durationHours);
                    }
                    ShiftOfOT = ship;


                    htable    = Att_RosterServices.GetRosterTable(false, profile, dateWorkDate, dateWorkDate.AddHours(durationHours), lstRosterGroup, lstRosterTypeGroup);
                    isWorkDay = Att_AttendanceServices.IsWorkDay(gradeCfg, htable, lstDayOff, dateWorkDate.AddHours(durationHours));

                    #endregion
                }

                //Kiem tra xem co trong thoi gian nghi thai san khong?
                if (isWorkDay && overtime.DurationType == EnumDropDown.OvertimeDurationType.E_OT_LATE.ToString() &&
                    _LstPregnancy != null && _LstPregnancy.Exists(pc => pc.ProfileID == profile.ID && pc.DateEnd >= dateWorkDate && pc.DateStart <= dateWorkDateEnd))
                {
                    dateWorkDate    = dateWorkDate.AddHours(-1);
                    dateWorkDateEnd = dateWorkDate.AddHours(durationHours);
                }
                overtime.WorkDate = dateWorkDate;



                string strHoursNightFrom = string.Empty;
                string strHoursNightTo   = string.Empty;


                if (!Att_AttendanceServices.IsNightShiftByConfig(ByPeriodOfTime) && ShiftOfOT != null &&
                    ShiftOfOT.NightTimeStart != null &&
                    ShiftOfOT.NightTimeEnd != null)
                {
                    strHoursNightFrom = ShiftOfOT.NightTimeStart.Value.ToString("HH:mm:ss");
                    strHoursNightTo   = ShiftOfOT.NightTimeEnd.Value.ToString("HH:mm:ss");
                }
                else
                {
                    strHoursNightFrom = string.IsNullOrEmpty(nightShiftFrom.Value1) == true ? "21:00:00" : nightShiftFrom.Value1 + ":00";
                    strHoursNightTo   = string.IsNullOrEmpty(nightShiftTo.Value1) == true ? "05:00:00" : nightShiftTo.Value1 + ":00";
                }

                DateTime dateNightFrom = Common.ConvertStringToDateTime(dateWorkDate.Date.ToString("MM/dd/yyyy") + " " + strHoursNightFrom, CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern);
                DateTime dateNightTo   = Common.ConvertStringToDateTime(dateWorkDate.Date.AddDays(1).ToString("MM/dd/yyyy") + " " + strHoursNightTo, CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern);


                OvertimeInfo overtimeInfo = new OvertimeInfo(true);
                overtimeInfo.DateFrom   = dateWorkDate;
                overtimeInfo.TotalHours = overtime.RegisterHours;

                overtimeInfo.DayShiftPoints = new DateTime[] { dateNightTo };

                if (isNocutOvertimePassDay)
                {
                    overtimeInfo.NightShiftPoints = new DateTime[] { dateNightFrom };
                }
                else
                {
                    //truong hop cat khi qua ngay hom sau
                    overtimeInfo.NightShiftPoints = new DateTime[] { dateNightFrom, dateNightFrom.Date };
                }

                if (ShiftOfOT != null && isAllowCutBreakHour)
                {
                    Cat_Shift shift      = ShiftOfOT;
                    DateTime  coBreakOut = shift.InTime.AddHours(shift.CoBreakIn);

                    if (shift.CoBreakOut - shift.CoBreakIn > 0)
                    {
                        overtimeInfo.BreaktPoints.Add(coBreakOut, shift.CoBreakOut - shift.CoBreakIn);
                    }
                }
                Hre_Profile temp = new Hre_Profile();
                temp.ID = overtime.ProfileID;

                overtimeInfo.Hre_Profile = temp;
                overtimeInfo.ListDayOff  = lstDayOff;

                listOvertimeInsert = AnalysisOvertime(overtime, overtimeInfo);



                return(listOvertimeInsert);
            }
        }