Esempio n. 1
0
        public ActionResult ExportWordProfileWaitingHireByTemplate(List<Guid> selectedIds, string valueFields)
        {
            string messages = string.Empty;
            DateTime DateStart = DateTime.Now;
            string dirpath = Common.GetPath(Common.DownloadURL); ;
            if (!Directory.Exists(dirpath))
            {
                Directory.CreateDirectory(dirpath);
            }

            ActionService baseService = new ActionService(UserLogin);
            string status = string.Empty;
            var objs = new List<object>();
            string strIDs = string.Empty;
            foreach (var item in selectedIds)
            {
                strIDs += Common.DotNetToOracle(item.ToString()) + ",";
            }
            if (strIDs.IndexOf(",") > 0)
                strIDs = strIDs.Substring(0, strIDs.Length - 1);
            objs.Add(strIDs);
            var lstProfileWaitingHire = baseService.GetData<Hre_ProfileEntity>(objs, ConstantSql.hrm_hr_sp_get_ProfileWaitingHireByListId, ref status);
            if (lstProfileWaitingHire == null)
                return null;
            int i = 0;

            String suffix = DateStart.ToString("_ddMMyyyyHHmmss");
            string folferPath = string.Empty;
            string folderName = "ExportHre_ProfileWaitingHire" + suffix;
            if (lstProfileWaitingHire.Count > 1)
            {
                folferPath = dirpath + "/" + folderName;
                Directory.CreateDirectory(folferPath);
            }
            else
            {
                folferPath = dirpath;
            }
            var fileDoc = string.Empty;
            int count = 0;

            var lstcandidateGeneralByProfileIDs = baseService.GetData<Hre_CandidateGeneralEntity>(strIDs, ConstantSql.hrm_hr_sp_get_CandidateGeneralByProfileIDs, ref status);
            #region ds nguoi than cua nhan vien duoc chon
            string strProfileIDs = "";
            if (selectedIds != null)
            {
                foreach (var ProfileID in selectedIds)
                {
                    string _strProfileID = Common.DotNetToOracle(ProfileID.ToString());
                    strProfileIDs += _strProfileID + ",";
                }
            }
            var lstRelativeByProfileIDs = baseService.GetData<Hre_RelativesEntity>(strProfileIDs, ConstantSql.hrm_hr_sp_get_RelativeByProfileIds, ref status);
            #endregion

            foreach (var objProfileWaitingHire in lstProfileWaitingHire)
            {
                var candidateGeneralByProfile = lstcandidateGeneralByProfileIDs.Where(s => s.ProfileID == objProfileWaitingHire.ID).FirstOrDefault();
                if (objProfileWaitingHire.DateHire.HasValue)
                {
                    objProfileWaitingHire.DateHireFormat = objProfileWaitingHire.DateHire.Value.ToString("dd/MM/yyyy");
                    objProfileWaitingHire.DayOfDateHire = objProfileWaitingHire.DateHire.Value.Day;
                    objProfileWaitingHire.MonthOfDateHire = objProfileWaitingHire.DateHire.Value.Month;
                    objProfileWaitingHire.YearOfDateHire = objProfileWaitingHire.DateHire.Value.Year;
                    objProfileWaitingHire.DateHireFormatEN = objProfileWaitingHire.DateHire.Value.ToString("dd-MMM-yyyy");
                }
                if (objProfileWaitingHire.DateEndProbation.HasValue)
                {
                    objProfileWaitingHire.DateEndProbationFormat = objProfileWaitingHire.DateEndProbation.Value.ToString("dd/MM/yyyy");
                    objProfileWaitingHire.DayOfDateProbation = objProfileWaitingHire.DateEndProbation.Value.Day;
                    objProfileWaitingHire.MonthOfDateProbation = objProfileWaitingHire.DateEndProbation.Value.Month;
                    objProfileWaitingHire.YearOfDateProbation = objProfileWaitingHire.DateEndProbation.Value.Year;
                    objProfileWaitingHire.DateEndProbationFormatEN = objProfileWaitingHire.DateEndProbation.Value.ToString("dd-MM-yyyy");
                }

                objProfileWaitingHire.DateNow = DateTime.Now.ToString("dd/MM/yyyy");

                if (objProfileWaitingHire.Gender != null)
                {
                    if (objProfileWaitingHire.Gender == "E_MALE")
                    {
                        objProfileWaitingHire.NameByGerder = "Anh";
                    }
                    else if (objProfileWaitingHire.Gender == "E_FEMALE")
                    {
                        objProfileWaitingHire.NameByGerder = "Chị";
                    }
                }
                if (objProfileWaitingHire.Gender == "E_FEMALE")
                {
                    //objProfileWaitingHire.GenderView = "Ms." + objProfileWaitingHire.ProfileName.Substring(objProfileWaitingHire.ProfileName.LastIndexOf(' '));
                    objProfileWaitingHire.GenderView = "Ms." + objProfileWaitingHire.ProfileName != null ? objProfileWaitingHire.ProfileName.Trim() : string.Empty;
                }
                else if (objProfileWaitingHire.Gender == "E_FEMALE")
                {
                    //objProfileWaitingHire.GenderView = "Mr." + objProfileWaitingHire.ProfileName.Substring(objProfileWaitingHire.ProfileName.LastIndexOf(' '));
                    objProfileWaitingHire.GenderView = "Mr." + objProfileWaitingHire.ProfileName != null ? objProfileWaitingHire.ProfileName.Trim() : string.Empty;
                }
                objProfileWaitingHire.DateNow = DateTime.Now.ToString("dd/MM/yyyy");
                objProfileWaitingHire.DateNow_Day = DateTime.Now.Day.ToString();
                objProfileWaitingHire.DateNow_Month = DateTime.Now.Month.ToString();
                objProfileWaitingHire.DateNow_Year = DateTime.Now.Year.ToString();
                objProfileWaitingHire.SalaryFormat = String.Format("{0:0,0}", objProfileWaitingHire.Salary);
                // Lấy thông tin HĐ
                if (objProfileWaitingHire.Allowance1 != null)
                    objProfileWaitingHire.Allowance1Format = String.Format("{0:0,0}", objProfileWaitingHire.Allowance1);
                if (objProfileWaitingHire.Allowance2 != null)
                    objProfileWaitingHire.Allowance2Format = String.Format("{0:0,0}", objProfileWaitingHire.Allowance2);
                if (objProfileWaitingHire.Allowance3 != null)
                    objProfileWaitingHire.Allowance3Format = String.Format("{0:0,0}", objProfileWaitingHire.Allowance3);
                if (objProfileWaitingHire.Allowance4 != null)
                    objProfileWaitingHire.Allowance4Format = String.Format("{0:0,0}", objProfileWaitingHire.Allowance4);
                objProfileWaitingHire.AllowanceID1Name = candidateGeneralByProfile != null ? candidateGeneralByProfile.AllowanceID1Name : null;
                objProfileWaitingHire.AllowanceID2Name = candidateGeneralByProfile != null ? candidateGeneralByProfile.AllowanceID2Name : null;
                objProfileWaitingHire.AllowanceID3Name = candidateGeneralByProfile != null ? candidateGeneralByProfile.AllowanceID3Name : null;
                objProfileWaitingHire.AllowanceID4Name = candidateGeneralByProfile != null ? candidateGeneralByProfile.AllowanceID5Name : null;
                if (objProfileWaitingHire.DateOfBirth != null)
                {
                    objProfileWaitingHire.DateOfBirthFormat = objProfileWaitingHire.DateOfBirth.Value.ToString("dd/MM/yyyy");
                }
                if (objProfileWaitingHire.SalaryClassID != null)
                {
                    var rankdetailbyProfile = baseService.GetData<Cat_SalaryRankEntity>(Common.DotNetToOracle(objProfileWaitingHire.SalaryClassID.ToString()), ConstantSql.hrm_cat_sp_get_SalaryRankBySalaryClassId, ref status).FirstOrDefault();
                    if (rankdetailbyProfile != null)
                    {
                        objProfileWaitingHire.Salary = rankdetailbyProfile.SalaryStandard;
                    }
                }
                var lstunusualallowancebyprofile = baseService.GetData<Sal_UnusualAllowanceEntity>(objProfileWaitingHire.ID, ConstantSql.hrm_sal_sp_get_UnusualAllowanceByProfileid, ref status);
                if (lstunusualallowancebyprofile != null)
                {
                    var PhuCapvung = lstunusualallowancebyprofile.Where(s => s.UnusualEDTypeCode == "PhuCapVung").ToList().FirstOrDefault();
                    var PhucapConNho = lstunusualallowancebyprofile.Where(s => s.UnusualEDTypeCode == "ChildCare").ToList().FirstOrDefault();
                    objProfileWaitingHire.PCArea = PhuCapvung.Amount;
                    objProfileWaitingHire.PCConNho = PhucapConNho.Amount;
                }
                //var contractbyprofile = baseService.GetData<Hre_ContractEntity>(Common.DotNetToOracle(objProfileWaitingHire.ID.ToString()), ConstantSql.hrm_hr_sp_get_ContractsByProfileId, ref status);
                //if(contractbyprofile != null)
                //{
                //    var contractEntity = contractbyprofile.OrderByDescending(s => s.DateCreate).Select(s => new {s.AllowanceID1, s.AllowanceID2, s.AllowanceID3, s.AllowanceID4}).ToList();
                //    if(contractEntity != null)
                //    {

                //        var allowance1 = listUsualAllowance.Where(s => contractEntity.Contains(s.ID) && s.Code == "").FirstOrDefault();
                //    }
                //}
                ActionService service = new ActionService(UserLogin);
                Cat_ExportEntity template = null;
                string outputPath = string.Empty;
                List<object> lstObjExport = new List<object>();
                lstObjExport.Add(null);
                lstObjExport.Add(null);
                lstObjExport.Add(null);
                lstObjExport.Add(null);
                lstObjExport.Add(1);
                lstObjExport.Add(10000000);
                if (!string.IsNullOrEmpty(valueFields))
                {
                    template = service.GetData<Cat_ExportEntity>(Guid.Parse(valueFields), ConstantSql.hrm_cat_sp_get_ExportById, ref status).FirstOrDefault();
                }

                if (template == null)
                {
                    messages = "Error";
                    return Json(messages, JsonRequestBehavior.AllowGet);
                }
                string templatepath = Common.GetPath(Common.TemplateURL + template.TemplateFile);
                outputPath = folferPath + "/" + Common.ChuyenTVKhongDau(objProfileWaitingHire.ProfileName) + suffix + i.ToString() + "_" + template.TemplateFile;
                fileDoc = NotificationType.Success.ToString() + "," + Common.DownloadURL + "/" + Common.ChuyenTVKhongDau(objProfileWaitingHire.ProfileName) + suffix + i.ToString() + "_" + template.TemplateFile;
                var ilContract = new List<Hre_ProfileEntity>();
                ilContract.Add(objProfileWaitingHire);

                #region lay nguoi than cua tung nhan vien
                List<Hre_RelativesEntity> lstRelativeByProfileID = new List<Hre_RelativesEntity>();
                if (lstRelativeByProfileIDs != null)
                {
                    lstRelativeByProfileID = lstRelativeByProfileIDs.Where(s => s.ProfileID == objProfileWaitingHire.ID).ToList();
                }

                #endregion

                var lstcontract = new List<Hre_ProfileEntity>();
                lstcontract.Add(objProfileWaitingHire);
                Hre_ProfileEntity objProfile = new Hre_ProfileEntity();
                DataTable tblProfiles = new DataTable();
                tblProfiles = lstcontract.Translate();
                DataTable tblRelatives = new DataTable();
                tblRelatives = lstRelativeByProfileID.Translate();
                DataSet dsData = new DataSet();
                dsData.Tables.Add(tblProfiles);
                dsData.Tables.Add(tblRelatives);
                dsData.Tables[0].TableName = "tblProfiles";
                dsData.Tables[1].TableName = "tblRelatives";

                //ExportService.ExportWord(outputPath, templatepath, dsData);
                ExportService.ExportWithRegions(outputPath, templatepath, dsData);
            }

            if (lstProfileWaitingHire.Count > 1)
            {
                var fileZip = Common.MultiExport("", true, folderName);
                return Json(fileZip);
            }
            return Json(fileDoc);
        }
Esempio n. 2
0
        public ActionResult GetProfileQuitList([DataSourceRequest] DataSourceRequest request, Hre_ProfileQuitSearchModel model)
        {
            var profileServices = new Hre_ProfileServices();
            var service = new ActionService(UserLogin);
            bool isGroup = profileServices.IsGroupByOrgProfileQuit();

            if (isGroup == true)
            {
                #region Group theo DS phòng ban - DDF
                var rptServices = new Hre_ReportServices();
                string status = string.Empty;

                var orgServices = new Cat_OrgStructureServices();
                var lstObjOrg = new List<object>();
                lstObjOrg.Add(null);
                lstObjOrg.Add(null);
                lstObjOrg.Add(null);
                lstObjOrg.Add(1);
                lstObjOrg.Add(int.MaxValue - 1);
                var lstOrg = service.GetData<Cat_OrgStructureEntity>(lstObjOrg, ConstantSql.hrm_cat_sp_get_OrgStructure, ref status).ToList();

                var orgTypeService = new Cat_OrgStructureTypeServices();
                var lstObjOrgType = new List<object>();
                lstObjOrgType.Add(null);
                lstObjOrgType.Add(null);
                lstObjOrgType.Add(1);
                lstObjOrgType.Add(int.MaxValue - 1);
                var lstOrgType = service.GetData<Cat_OrgStructureTypeEntity>(lstObjOrgType, ConstantSql.hrm_cat_sp_get_OrgStructureType, ref status).ToList();

                ListQueryModel lstModel = new ListQueryModel
                {
                    PageIndex = request.Page,
                    PageSize = request.PageSize,
                    Filters = ExtractFilterAttributes(request),
                    Sorts = ExtractSortAttributes(request),
                    AdvanceFilters = ExtractAdvanceFilterAttributes(model)
                };
                var lstEntity = service.GetData<Hre_ProfileEntity>(lstModel, ConstantSql.hrm_hr_sp_get_ProfileQuit, ref status);
                var lstProfileEntity = new List<Hre_ProfileEntity>();
                var lstProfileModel = new List<Hre_ProfileModel>();

                if (lstEntity != null)
                {
                    request.Page = 1;
                    foreach (var item in lstEntity)
                    {
                        var profileEntity = new Hre_ProfileEntity();
                        var orgName = new List<string>();
                        if (item.OrgStructureID != null)
                        {
                            orgName = rptServices.GetParentOrgName(lstOrg, lstOrgType, item.OrgStructureID);
                        }
                        // orgName = rptServices.GetParentOrgName(lstOrg, lstOrgType, item.OrgStructureID);
                        if (orgName.Count == 0)
                            continue;
                        if (orgName.Count < 3)
                        {
                            orgName.Insert(0, string.Empty);
                            if (orgName.Count < 3)
                            {
                                orgName.Insert(0, string.Empty);
                            }
                        }
                        profileEntity = item.CopyData<Hre_ProfileEntity>();
                        profileEntity.Channel = orgName[2];
                        profileEntity.Region = orgName[1];
                        profileEntity.Area = orgName[0];
                        lstProfileEntity.Add(profileEntity);
                    }
                    lstProfileModel = lstProfileEntity.Translate<Hre_ProfileModel>();
                    var dataSourceResult = lstProfileModel.ToDataSourceResult(request);
                    if (lstProfileModel.FirstOrDefault().GetPropertyValue("TotalRow") != null)
                    {
                        dataSourceResult.Total = lstProfileModel.Count() <= 0 ? 0 : (int)lstProfileModel.FirstOrDefault().GetPropertyValue("TotalRow");
                    }

                    return Json(dataSourceResult, JsonRequestBehavior.AllowGet);
                }
                #endregion
            }
            return GetListDataAndReturn<Hre_ProfileModel, Hre_ProfileEntity, Hre_ProfileQuitSearchModel>(request, model, ConstantSql.hrm_hr_sp_get_ProfileQuit);

        }
Esempio n. 3
0
        /// <summary> Set Data vào hashtable theo trạng thái </summary>
        /// <param name="hsData"></param>
        /// <param name="profile"></param>
        /// <param name="d02Reports"></param>
        /// <param name="_status">Trạng thái Group (Tăng , Giảm)</param>
        /// <param name="_status1">Trạng thai (tăng lao động,giảm lao động , giảm thai sản....)</param>
        /// <param name="_firstSal">Mức đóng tháng trước</param>
        /// <param name="_currentSal">Mức đóng tháng này</param>
        /// <param name="monthYear"></param>
        /// <param name="orgStructures"></param>
        /// <param name="orderGroup"></param>
        /// <returns></returns>
        private Hashtable SetHashtableData(Hashtable hsData, Hre_ProfileEntity profile, ref List<Ins_InsuranceReportD02Entity> d02Reports, string _status, String _status1, double? _firstSal, double? _currentSal, DateTime monthYear, List<Cat_OrgStructureEntity> orgStructures, string orderGroup)
        {
            bool isHOnda = true;
            _firstSal = _firstSal ?? 0;
            _currentSal = _currentSal ?? 0;
            var rptD02 = SetReportD02(profile, _status1, _firstSal.Value, _currentSal.Value, monthYear, orgStructures, _status, orderGroup);

            #region Xử Lý Gôm Nhóm Trạng Thái D02 - Dành cho Honda
            //honda
            //set lai status1 
            if (isHOnda)
            {
                if (_status1 == TypeInsuranceD02TS.E_TANG_TS.ToString() || _status1 == TypeInsuranceD02TS.E_TANG_LEAVE_14WORKINGDAYS.ToString()
                    || _status1 == TypeInsuranceD02TS.E_TANG_BENH.ToString() || _status1 == TypeInsuranceD02TS.E_TANG_BHYT.ToString())
                {
                    _status1 = TypeInsuranceD02TS.E_TANG_LD.ToString();
                }
                if (_status1 == TypeInsuranceD02TS.E_GIAM_TS_QUIT.ToString() || _status1 == TypeInsuranceD02TS.E_GIAM_TS.ToString()
                    || _status1 == TypeInsuranceD02TS.E_GIAM_BENH.ToString() || _status1 == TypeInsuranceD02TS.E_GIAM_LD_BHYT.ToString()
                    || _status1 == TypeInsuranceD02TS.E_GIAM_LD_NOT_BHYT.ToString()
                    || _status1 == TypeInsuranceD02TS.E_GIAM_LEAVE_PREMONTH_14WORKINGDAYS.ToString()
                    || _status1 == TypeInsuranceD02TS.E_GIAM_LEAVE_14WORKINGDAYS.ToString()
                    || _status1 == TypeInsuranceD02TS.E_GIAM_PREGNANT_14WORKINGDAYS.ToString()
                    || _status1 == TypeInsuranceD02TS.E_GIAM_QUIT_SUSPENSE.ToString()
                    )
                {
                    _status1 = TypeInsuranceD02TS.E_GIAM_LD.ToString();
                }
                if (_status1 == TypeInsuranceD02TS.E_GIAM_LUONG_CHANGEJOBNAME.ToString())
                {
                    _status1 = TypeInsuranceD02TS.E_GIAM_LUONG.ToString();
                }

                if (_status1 == TypeInsuranceD02TS.E_TANG_LUONG_CHANGEJOBNAME.ToString())
                {
                    _status1 = TypeInsuranceD02TS.E_TANG_LUONG.ToString();
                }
            }

            #endregion

            if (!hsData.ContainsKey(_status1))
            {
                d02Reports = new List<Ins_InsuranceReportD02Entity>();
                rptD02.STT = "1";
                d02Reports.Add(rptD02);
                hsData.Add(_status1, d02Reports);
            }
            else
            {
                var lstInsurances = (List<Ins_InsuranceReportD02Entity>)hsData[_status1];
                rptD02.STT = (lstInsurances.Count + 1).ToString();
                if (!lstInsurances.Any(m => m.Status == rptD02.Status && m.ProfileID == rptD02.ProfileID))
                {
                    lstInsurances.Add(rptD02);
                    hsData[_status1] = lstInsurances;
                }
            }
            return hsData;
        }
Esempio n. 4
0
        public ActionResult ExportProfileWorkingByTemplate(List<Guid> selectedIds, string valueFields)
        {
            var actionService = new ActionService(UserLogin);
            //string folderStore = DateTime.Now.ToString("ddMMyyyyHHmmss");
            DateTime DateStart = DateTime.Now;
            string messages = string.Empty;
            string dirpath = Common.GetPath(Common.DownloadURL); ;
            if (!Directory.Exists(dirpath))
                Directory.CreateDirectory(dirpath);

            string status = string.Empty;
            var contractServices = new Hre_ContractServices();
            var ActionService = new ActionService(UserLogin);
            var baseService = new BaseService();
            var objs = new List<object>();
            string strIDs = string.Empty;
            foreach (var item in selectedIds)
            {
                strIDs += Common.DotNetToOracle(item.ToString()) + ",";
            }
            if (strIDs.IndexOf(",") > 0)
                strIDs = strIDs.Substring(0, strIDs.Length - 1);
            objs.Add(strIDs);
            var lstProfile = baseService.GetData<Hre_ProfileEntity>(objs, ConstantSql.hrm_hr_sp_get_ProfileWorkingByListId, UserLogin, ref status);
            if (lstProfile == null)
                return null;
            int i = 0;
            var lstProfileID = lstProfile.Select(s => s.ID).Distinct().ToList();
            String suffix = DateStart.ToString("_ddMMyyyyHHmmss");
            string folferPath = string.Empty;
            string folderName = "ExportHre_Contract" + suffix;
            if (lstProfileID.Count > 1)
            {
                folferPath = dirpath + "/" + folderName;
                Directory.CreateDirectory(folferPath);
            }
            else
            {
                folferPath = dirpath;
            }
            var fileDoc = string.Empty;
            #region ds nguoi than cua nhan vien duoc chon
            string strProfileIDs = "";
            if (lstProfileID != null)
            {
                foreach (var ProfileID in lstProfileID)
                {
                    string _strProfileID = Common.DotNetToOracle(ProfileID.ToString());
                    strProfileIDs += _strProfileID + ",";
                }
            }
            var lstRelativeByProfileIDs = ActionService.GetData<Hre_RelativesEntity>(strProfileIDs, ConstantSql.hrm_hr_sp_get_RelativeByProfileIds, ref status);
            #endregion

            foreach (var profile in lstProfile)
            {
                if (profile.IDDateOfIssue.HasValue)
                    profile.IDDateOfIssueFormat = profile.IDDateOfIssue.Value.ToString("dd/MM/yyyy");
                if (profile.DateOfBirth.HasValue)
                    profile.DateOfBirthFormat = profile.DateOfBirth.Value.ToString("dd/MM/yyyy");
                if (profile.Salary != null)
                    profile.SalaryFormat = String.Format("{0:0,0}", profile.Salary);
                if (profile.Allowance1 != null)
                    profile.Allowance1Format = String.Format("{0:0,0}", profile.Allowance1);

                if (profile.DayOfBirth > 0 && profile.MonthOfBirth > 0 && profile.YearOfBirth > 0)
                {
                    profile.Birthday = profile.DayOfBirth + "/" + profile.MonthOfBirth + "/" + profile.YearOfBirth;
                }
                if (profile.DateHire.HasValue)
                {
                    profile.DateHireFormat = profile.DateHire.Value.ToString("dd/MM/yyyy");
                }
                profile.DateNow = DateTime.Now.ToString("dd/MM/yyyy");
                if (profile.DateStart.HasValue)
                {
                    profile.DateStartString = "Ngày " + profile.DateStart.Value.Day + " Tháng " + profile.DateStart.Value.Month + " Năm " + profile.DateStart.Value.Year + " ";
                    profile.DateStartFormat = profile.DateStart.Value.ToString("dd/MM/yyyy");
                }
                if (profile.DateEnd.HasValue)
                {
                    profile.DateEndString = "Ngày " + profile.DateEnd.Value.Day + " Tháng " + profile.DateEnd.Value.Month + " Năm " + profile.DateEnd.Value.Year + " ";
                    profile.DateEndFormat = profile.DateEnd.Value.ToString("dd/MM/yyyy");
                }
                ActionService service = new ActionService(UserLogin);
                var exportService = new Cat_ExportServices();
                Cat_ExportEntity template = null;
                string outputPath = string.Empty;
                List<object> lstObjExport = new List<object>();
                lstObjExport.Add(null);
                lstObjExport.Add(null);
                lstObjExport.Add(null);
                lstObjExport.Add(null);
                lstObjExport.Add(1);
                lstObjExport.Add(10000000);

                if (!string.IsNullOrEmpty(valueFields))
                {
                    template = actionService.GetData<Cat_ExportEntity>(Guid.Parse(valueFields), ConstantSql.hrm_cat_sp_get_ExportById, ref status).FirstOrDefault();
                }

                if (template == null)
                {
                    messages = "Error";
                    return Json(messages, JsonRequestBehavior.AllowGet);
                }

                string templatepath = Common.GetPath(Common.TemplateURL + template.TemplateFile);

                if (!System.IO.File.Exists(templatepath))
                {
                    messages = "NotTemplate";
                    return Json(messages, JsonRequestBehavior.AllowGet);
                }
                outputPath = folferPath + "/" + Common.ChuyenTVKhongDau(profile.ProfileName) + suffix + i.ToString() + "_" + template.TemplateFile;
                fileDoc = NotificationType.Success.ToString() + "," + Common.DownloadURL + "/" + Common.ChuyenTVKhongDau(profile.ProfileName) + suffix + i.ToString() + "_" + template.TemplateFile;
                if (!System.IO.File.Exists(templatepath))
                {
                    messages = "NotTemplate";
                    return Json(messages, JsonRequestBehavior.AllowGet);
                }
                #region lay nguoi than cua tung nhan vien
                List<Hre_RelativesEntity> lstRelativeByProfileID = new List<Hre_RelativesEntity>();
                if (lstRelativeByProfileIDs != null)
                {
                    lstRelativeByProfileID = lstRelativeByProfileIDs.Where(s => s.ProfileID == profile.ID).ToList();
                }

                #endregion

                var lstcontract = new List<Hre_ProfileEntity>();
                lstcontract.Add(profile);
                Hre_ProfileEntity objProfile = new Hre_ProfileEntity();
                //string[] FieldtblProfiles = new string[] { "ProfileName","ID"};
                //DataTable tblProfiles = Common.ConvertIListToDataTable(lstcontract, FieldtblProfiles);
                DataTable tblProfiles = new DataTable();
                tblProfiles = lstcontract.Translate();
                DataTable tblRelatives = new DataTable();
                tblRelatives = lstRelativeByProfileID.Translate();
                //Common.ConvertIListToDataTable(lstRelativeByProfileID, FieldtblRelatives);
                DataSet dsData = new DataSet();
                dsData.Tables.Add(tblProfiles);
                dsData.Tables.Add(tblRelatives);
                dsData.Tables[0].TableName = "tblProfiles";
                dsData.Tables[1].TableName = "tblRelatives";

                //ExportService.ExportWord(outputPath, templatepath, dsData);
                ExportService.ExportWithRegions(outputPath, templatepath, dsData);
            }
            if (lstProfileID.Count > 1)
            {
                var fileZip = Common.MultiExport("", true, folderName);
                return Json(fileZip);
            }
            return Json(fileDoc);
        }
Esempio n. 5
0
        /// <summary>
        /// Hàm chạy tính hết tất cả các formula có trong grade
        /// </summary>
        /// <param name="listElementFormula"></param>
        /// <param name="listElement"></param>
        /// <param name="TotalData"></param>
        /// <param name="profileItem"></param>
        /// <param name="CutOffDuration"></param>
        /// <param name="listTmpDeduction"></param>
        /// <returns></returns>
        public List<ElementFormula> ParseElementFormula(List<ElementFormula> listElementFormula, List<Cat_ElementEntity> listGradeElement, ComputePayrollDataModel TotalData, Hre_ProfileEntity profileItem, Att_CutOffDurationEntity CutOffDuration, Dictionary<Guid, ValueCount> listTmpDeduction, bool ComputeOrderNumber, TraceLogManager FileLog)
        {
            if (ComputeOrderNumber)
            {
                listGradeElement = listGradeElement.OrderBy(m => m.OrderNumber).ToList();
                foreach (var elementItem in listGradeElement)
                {
                    try
                    {
                        listElementFormula = GetStaticValues(TotalData, listElementFormula, profileItem, CutOffDuration, elementItem.ElementCode, listTmpDeduction);
                        var result = FormulaHelper.ParseFormula(elementItem.Formula.Replace("[", "").Replace("]", ""), listElementFormula.Distinct().ToList());
                        listElementFormula.Add(new ElementFormula(elementItem.ElementCode, result.Value, 0, result.ErrorMessage));
                        //listElementFormula = ParseFormula(elementItem, listElementFormula, TotalData, profileItem, CutOffDuration, listTmpDeduction);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(elementItem.ElementCode);
                    }
                }
            }
            else
            {
                foreach (var elementItem in listGradeElement)
                {

                    try
                    {
                        listElementFormula = ParseFormula(elementItem, listElementFormula, TotalData, profileItem, CutOffDuration, listTmpDeduction);

                    }
                    catch (Exception ex)
                    {
                        throw new Exception(elementItem.ElementCode);
                    }

                }
            }
            return listElementFormula;
        }
Esempio n. 6
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();
        }
Esempio n. 7
0
        private static void GetAllowanceInsuranceByFomular(double salInsurance, DateTime monthCheck, List<Hre_HDTJob> hreHDTJobs, Att_CutOffDuration cutOffDuration, Hre_ProfileEntity profile, Cat_GradePayroll gradePayroll, out Hre_HDTJob hreHdtJobProfile, out FormulaHelper.FormulaHelperModel result, List<Cat_UnusualAllowanceCfg> lstUnusualAllowanceCfg, List<Sal_UnusualAllowance> lstUnusualAllowance, List<Cat_Element> listElementFormulaInDB, double hdt4Amount, double hdt5Amount)
        {
            string fomular = (new InsuranceServices()).FomularReplace(gradePayroll.FormulaSalaryIns, listElementFormulaInDB);

            List<ElementFormula> listElementFormula = new List<ElementFormula>();
            hreHdtJobProfile = hreHDTJobs.Where(m => m.ProfileID == profile.ID && m.Status == HDTJobStatus.E_APPROVE.ToString()).OrderBy(m => m.DateFrom).FirstOrDefault();

            #region Công Loại IV
            var listHDTJob_Type4 = hreHDTJobs.Where(m => m.Status == HDTJobStatus.E_APPROVE.ToString() && m.Type == EnumDropDown.HDTJobType.E_TYPE4.ToString() && m.ProfileID == profile.ID).OrderBy(m => m.DateFrom).ToList();
            double TotalDayHDTJob4 = 0;
            if (listHDTJob_Type4 != null && listHDTJob_Type4.Count > 0)
            {
                TotalDayHDTJob4 = profile.NumdayHDTJobTypeIV ?? 0;
            }

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

            #region Công Loại V
            var listHDTJob_Type5 = hreHDTJobs.Where(m => m.Status == HDTJobStatus.E_APPROVE.ToString() && m.Type == EnumDropDown.HDTJobType.E_TYPE5.ToString() && m.ProfileID == profile.ID).OrderBy(m => m.DateFrom).ToList();
            double TotalDayHDTJob5 = 0;
            if (listHDTJob_Type5 != null && listHDTJob_Type5.Count > 0)
            {
                TotalDayHDTJob5 = profile.NumdayHDTJobTypeV ?? 0;
            }

            #region set hre_hdtjob có có ngày làm hdtjob lớn hơn
            if (TotalDayHDTJob4 >= TotalDayHDTJob5)
            {
                hreHdtJobProfile = listHDTJob_Type4.FirstOrDefault();
            }
            else
            {
                hreHdtJobProfile = listHDTJob_Type5.FirstOrDefault();
            }
            #endregion

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


            gradePayroll.FormulaSalaryIns = fomular;
            if (hreHdtJobProfile != null)
            {
                if (hreHdtJobProfile.DateFrom.HasValue)
                {
                    item = new ElementFormula(PayrollElement.HR_START_DATE_HDTJOB.ToString(), hreHdtJobProfile.DateFrom.Value, 0);
                    listElementFormula.Add(item);
                }
                if (hreHdtJobProfile.DateTo.HasValue)
                {
                    item = new ElementFormula(PayrollElement.HR_END_DATE_HDTJOB.ToString(), hreHdtJobProfile.DateTo.Value, 0);
                    listElementFormula.Add(item);
                }
                if (hreHdtJobProfile.DateTo.HasValue)
                {
                    item = new ElementFormula(PayrollElement.ATT_CUTOFFDURATION_MONTH.ToString(), monthCheck, 0);
                    listElementFormula.Add(item);
                }
            }
            if (gradePayroll.FormulaSalaryIns.Contains(PayrollElement.INS_SALARY_INSURANCE_ROOT.ToString()))
            {
                item = new ElementFormula(PayrollElement.INS_SALARY_INSURANCE_ROOT.ToString(), salInsurance, 0);
                listElementFormula.Add(item);
            }

            if (gradePayroll.FormulaSalaryIns.Contains(InsuranceElement.INS_JOBNAME_NUMDAYNONHDTJOB.ToString()))
            {
                item = new ElementFormula(InsuranceElement.INS_JOBNAME_NUMDAYNONHDTJOB.ToString(), profile.NumdayNonHDTJob, 0);
                listElementFormula.Add(item);
            }

            if (gradePayroll.FormulaSalaryIns.Contains(InsuranceElement.INS_HDT4_TIMELINE.ToString()))
            {
                item = new ElementFormula(InsuranceElement.INS_HDT4_TIMELINE.ToString(), hdt4Amount, 0);
                listElementFormula.Add(item);
            }
            if (gradePayroll.FormulaSalaryIns.Contains(InsuranceElement.INS_HDT5_TIMELINE.ToString()))
            {
                item = new ElementFormula(InsuranceElement.INS_HDT5_TIMELINE.ToString(), hdt5Amount, 0);
                listElementFormula.Add(item);
            }

            foreach (var Allowance in lstUnusualAllowanceCfg)
            {
                var unusualAllowance = lstUnusualAllowance.FirstOrDefault(m => m.ProfileID == profile.ID && m.UnusualEDTypeID == Allowance.ID);
                if (gradePayroll.FormulaSalaryIns.Contains(Allowance.Code) && unusualAllowance != null)
                {
                    item = new ElementFormula(Allowance.Code, unusualAllowance.Amount, 0);
                    listElementFormula.Add(item);
                }
            }

            //tinh tien HDTJob

            result = FormulaHelper.ParseFormula(fomular.Replace("[", "").Replace("]", ""), listElementFormula.Distinct().ToList());
        }
Esempio n. 8
0
        /// <summary>
        /// [Hieu.Van] Tồng hợp dữ liệu ăn
        /// </summary>
        /// <param name="request"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        //[HttpPost]
        public ActionResult GetLaundryRecordSummary([DataSourceRequest] DataSourceRequest request, Lau_LaundryRecordSearchModel model)
        {
            Lau_LaundryRecordServices LauService = new Lau_LaundryRecordServices();
            var baseService = new BaseService();
            var Actionservices = new ActionService(UserLogin);

            #region xử lý dateStart - dateEnd
            DateTime dateStart = DateTime.Now;
            DateTime dateEnd = DateTime.Now;
            if (model.DateFrom != null)
            {
                dateStart = model.DateFrom.Value;
            }
            if (model.DateTo != null)
            {
                dateEnd = model.DateTo.Value;
            }
            #endregion

            #region xử lý lấy lstProfileIds theo OrgStructureID
            List<Hre_ProfileEntity> lstProfileIDs = new List<Hre_ProfileEntity>();
            string status = string.Empty;
            List<object> lstObj = new List<object>();
            lstObj.Add(model.OrgStructureID);
            lstObj.Add(null);
            lstObj.Add(null);
            List<Hre_ProfileEntity> _temp = new List<Hre_ProfileEntity>();
            Hre_ProfileEntity t = new Hre_ProfileEntity();
            List<Hre_ProfileEntity> _profileIDs = new List<Hre_ProfileEntity>();
            var baseServices = new ActionService(UserLogin);
            if (model.ProfileIDs != null)
            {
                var lst = model.ProfileIDs.Split(',');
                foreach (var item in lst)
                {
                    t = new Hre_ProfileEntity();
                    Guid _Id = new Guid(item);
                    t.ID = _Id;
                    _temp.Add(t);
                }



                if (model.OrgStructureID != null)
                {

                    lstProfileIDs = Actionservices.GetData<Hre_ProfileEntity>(lstObj, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, ref status).ToList();
                    _profileIDs = lstProfileIDs.Where(m => !_temp.Contains(m)).ToList();
                    lstProfileIDs.AddRange(_profileIDs);
                }
                else
                {
                    lstProfileIDs = _temp;
                }
            }
            else
            {
                lstProfileIDs = Actionservices.GetData<Hre_ProfileEntity>(lstObj, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, ref status).ToList();
            }
            #endregion

            // Hàm xử lý tổng hợp
            var result = LauService.GetLaundryRecordSummary(model.LineID, model.LockerID, model.MarkerID, dateStart, dateEnd, lstProfileIDs, UserLogin).ToList().Translate<Lau_LaundryRecordModel>();
            if (result != null)
            {
                var submit = ConstantDisplay.HRM_Enum_Submit.TranslateString();
                var auto = ConstantDisplay.HRM_Enum_Auto.TranslateString();
                result.Where(s => s.Status == LaundryRecordStatus.E_SUBMIT.ToString()).Select(s => s.Status = submit).ToList();
                result.Where(s => s.Type == LaundryRecordType.E_AUTO.ToString()).Select(s => s.Type = auto).ToList();
            }
            #region xử lý xuất áo cáo
            if (model.IsExport)
            {
                var fullPath = ExportService.Export(result, model.ValueFields.Split(','));
                return Json(fullPath);
            }

            if (model.selectedIDs != null)
            {
                var strSelect = model.selectedIDs.Split(',');
                List<Guid> lstSelect = new List<Guid>();
                foreach (var item in strSelect)
                {
                    lstSelect.Add(new Guid(item));
                }
                var resultSelect = result.Where(m => lstSelect.Contains(m.ID)).ToList();
                var fullPath = ExportService.Export(resultSelect, model.ValueFields.Split(','));
                return Json(fullPath);
            }
            #endregion

            request.Page = 1;
            var dataSourceResult = result.ToDataSourceResult(request);
            //dataSourceResult.Total = result.Count() <= 0 ? 0 : result.FirstOrDefault().TotalRow;
            return Json(result.ToDataSourceResult(request));
        }
Esempio n. 9
0
        public DataTable GetReportSumaryShiftMonthList(DateTime dateStart, DateTime dateEnd, string OrgStructureTree, string ProfileDetail, string strShift, bool isNotAllowZero, bool isIncludeQuitEmp, string UserLogin)
        {
            string status = string.Empty;
            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoCat_Position = new CustomBaseRepository<Cat_Position>(unitOfWork);
                var repoCat_JobTitle = new CustomBaseRepository<Cat_JobTitle>(unitOfWork);
                var repoCat_Shift = new CustomBaseRepository<Cat_Shift>(unitOfWork);
                var repoCat_OrgStructure = new CustomBaseRepository<Cat_OrgStructure>(unitOfWork);
                var repoCat_OrgStructureType = new Cat_OrgStructureTypeRepository(unitOfWork);

                var orgTypes = repoCat_OrgStructureType.FindBy(s => s.IsDelete == null).ToList();
                List<Guid> orgIDs = new List<Guid>();
                if (OrgStructureTree != null)
                {
                    orgIDs = OrgStructureTree.Split(',').Select(s => Guid.Parse(s)).ToList();
                }
                List<Guid> shiftIDs = new List<Guid>();
                if (strShift != null)
                {
                    shiftIDs = strShift.Split(',').Select(s => Guid.Parse(s)).ToList();
                }

                List<object> lst3ParamSE = new List<object>();
                lst3ParamSE.Add(null);
                lst3ParamSE.Add(dateStart);
                lst3ParamSE.Add(dateEnd);
                var dataAtt_Workday = GetData<Att_Workday>(lst3ParamSE, ConstantSql.hrm_att_getdata_Workday, UserLogin, ref status).ToList();

                var workDays = dataAtt_Workday.Where(s => dateStart.Date <= s.WorkDate && s.WorkDate <= dateEnd.Date)
                   .Select(s => new { s.ProfileID, s.ShiftApprove, s.WorkDate }).ToList();
                var profileIds = workDays.Select(s => s.ProfileID).Distinct().ToList();

                #region xử lý lấy lstProfileIds theo OrgStructureID
                List<Hre_ProfileEntity> lstProfileIDs = new List<Hre_ProfileEntity>();
                List<object> lstParamPro = new List<object>();
                lstParamPro.Add(OrgStructureTree);
                lstParamPro.Add(null);
                lstParamPro.Add(null);
                if (ProfileDetail != null)
                {
                    List<Hre_ProfileEntity> _lstTemp = new List<Hre_ProfileEntity>();
                    List<Hre_ProfileEntity> _lstContains = new List<Hre_ProfileEntity>();
                    Hre_ProfileEntity proEntity = new Hre_ProfileEntity();

                    var lst = ProfileDetail.Split(',').Select(s => Guid.Parse(s)).ToList();
                    foreach (var item in lst)
                    {
                        proEntity = new Hre_ProfileEntity();
                        proEntity.ID = item;
                        _lstTemp.Add(proEntity);
                    }
                    if (OrgStructureTree != null)
                    {
                        lstProfileIDs = GetData<Hre_ProfileEntity>(lstParamPro, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, UserLogin, ref status);
                        _lstContains = lstProfileIDs.Where(m => !_lstTemp.Contains(m)).ToList();

                        if (_lstContains.Count > 0)
                        {
                            string selectedIds = Common.DotNetToOracle(String.Join(",", _lstContains.Select(s => s.ID.ToString()).ToList<string>()));
                            _lstTemp = GetData<Hre_ProfileEntity>(selectedIds, ConstantSql.hrm_hr_sp_get_ProfileByIds, UserLogin, ref status);
                            lstProfileIDs.AddRange(_lstTemp);
                        }
                    }
                    else
                    {
                        string selectedIds = Common.DotNetToOracle(ProfileDetail);
                        lstProfileIDs = GetData<Hre_ProfileEntity>(selectedIds, ConstantSql.hrm_hr_sp_get_ProfileByIds, UserLogin, ref status);
                    }
                }
                else
                {
                    lstProfileIDs = GetData<Hre_ProfileEntity>(lstParamPro, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, UserLogin, ref status);
                }
                #endregion


                var profiles = lstProfileIDs.Select(s => new { s.ID, s.DateQuit, s.OrgStructureID, s.ProfileName, s.CodeEmp, s.PositionID, s.JobTitleID }).ToList();
                var orgs = repoCat_OrgStructure.FindBy(s => s.Code != null).ToList();
                var positions = repoCat_Position.FindBy(s => s.Code != null).Select(s => new { s.ID, s.Code }).ToList();
                var jobtitles = repoCat_JobTitle.FindBy(s => s.Code != null).Select(s => new { s.ID, s.Code }).ToList();
                var shifts = repoCat_Shift.FindBy(s => s.Code != null).Select(s => new { s.ID, s.Code }).ToList();
                //var codeEmp = listFilterInfo.GetFilterValue1<string>(Hre_Profile.FieldNames.CodeEmp);
                if (orgIDs.Count > 0)
                {
                    profiles = profiles.Where(s => s.OrgStructureID != null && orgIDs.Contains(s.OrgStructureID.Value)).ToList();
                }
                if (shiftIDs.Count > 0)
                {
                    workDays = workDays.Where(s => s.ShiftApprove.HasValue && shiftIDs.Contains(s.ShiftApprove.Value)).ToList();
                    profileIds = workDays.Select(s => s.ProfileID).ToList();
                    profiles = profiles.Where(s => profileIds.Contains(s.ID)).ToList();
                }
                if (!isIncludeQuitEmp)
                {
                    profiles = profiles.Where(s => s.DateQuit == null || s.DateQuit > dateEnd).ToList();
                }
                //if (codeEmp.IsNotNullOrEmpty())
                //{
                //    profiles = profiles.Where(s => s.CodeEmp == codeEmp).ToList();
                //}
                profileIds = profiles.Select(s => s.ID).ToList();
                workDays = workDays.Where(s => profileIds.Contains(s.ProfileID)).ToList();

                var dataAtt_LeaveDay = GetData<Att_LeaveDayEntity>(lst3ParamSE, ConstantSql.hrm_att_getdata_LeaveDay_Inner, UserLogin, ref status).ToList();
                var leaveDays = dataAtt_LeaveDay.Where(s => profileIds.Contains(s.ProfileID) && dateStart <= s.DateEnd && s.DateStart <= dateEnd)
                    .Select(s => new { s.ProfileID, s.DateStart, s.DateEnd }).ToList();
                DataTable table = GetSchema_SumaryShiftMonth();
                var codes = repoCat_Shift.FindBy(s => s.Code != null).Select(s => s.Code).Distinct().ToList<string>();
                if (isNotAllowZero)
                {
                    var profileIDs = workDays.Select(s => s.ProfileID).ToList();
                    profiles = profiles.Where(s => profileIDs.Contains(s.ID)).ToList();
                }
                foreach (var profile in profiles)
                {
                    var workDayProfiles = workDays.Where(s => s.ProfileID == profile.ID).ToList();
                    var leaveDayProfiles = leaveDays.Where(s => s.ProfileID == profile.ID).ToList();
                    List<DateTime> dateLeavdays = new List<DateTime>();
                    foreach (var leaveDayProfile in leaveDayProfiles)
                    {
                        for (DateTime date = leaveDayProfile.DateStart; date <= leaveDayProfile.DateEnd; date = date.AddDays(1))
                        {
                            dateLeavdays.Add(date);
                        }
                    }
                    workDayProfiles = workDayProfiles.Where(s => !dateLeavdays.Contains(s.WorkDate)).ToList();
                    DataRow row = table.NewRow();

                    Guid? orgId = profile.OrgStructureID;
                    var orgBranch = LibraryService.GetNearestParent(orgId, OrgUnit.E_BRANCH, orgs, orgTypes);
                    var orgOrg = LibraryService.GetNearestParent(orgId, OrgUnit.E_DEPARTMENT, orgs, orgTypes);
                    var orgTeam = LibraryService.GetNearestParent(orgId, OrgUnit.E_TEAM, orgs, orgTypes);
                    var orgSection = LibraryService.GetNearestParent(orgId, OrgUnit.E_SECTION, orgs, orgTypes);

                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.BranchCode] = orgBranch != null ? orgBranch.Code : string.Empty;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.OrgStructureCode] = orgOrg != null ? orgOrg.Code : string.Empty;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.TeamCode] = orgTeam != null ? orgTeam.Code : string.Empty;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.SectionCode] = orgSection != null ? orgSection.Code : string.Empty;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.BranchName] = orgBranch != null ? orgBranch.OrgStructureName : string.Empty;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.OrgStructureName] = orgOrg != null ? orgOrg.OrgStructureName : string.Empty;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.TeamName] = orgTeam != null ? orgTeam.OrgStructureName : string.Empty;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.SectionName] = orgSection != null ? orgSection.OrgStructureName : string.Empty;
                    var positon = positions.FirstOrDefault(s => s.ID == profile.PositionID);
                    var jobtitle = jobtitles.FirstOrDefault(s => s.ID == profile.JobTitleID);
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.CodeEmp] = profile.CodeEmp;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.ProfileName] = profile.ProfileName;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.PositionCode] = positon != null ? positon.Code : string.Empty;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.JobtitleCode] = jobtitle != null ? jobtitle.Code : string.Empty;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.DateExport] = DateTime.Now;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.DateFrom] = dateStart;
                    row[Att_ReportSumaryShiftMonthEntity.FieldNames.DateTo] = dateEnd;
                    //row["UserExport"] = Session[SessionObjects.UserLogin];
                    foreach (string code in codes)
                    {
                        var shift = shifts.FirstOrDefault(s => s.Code == code);
                        var sum = workDayProfiles.Count(s => s.ShiftApprove == shift.ID);
                        row[code] = sum > 0 ? (object)sum : DBNull.Value;
                    }
                    table.Rows.Add(row);
                }
                var configs = new Dictionary<string, Dictionary<string, object>>();
                var config90 = new Dictionary<string, object>();
                var configdate = new Dictionary<string, object>();
                configdate.Add("format", "{0:dd/MM/yyyy}");
                configdate.Add("width", 110);
                config90.Add("width", 90);
                if (!configs.ContainsKey("CodeEmp"))
                    configs.Add("CodeEmp", config90);
                if (!configs.ContainsKey("TeamCode"))
                    configs.Add("TeamCode", config90);
                if (!configs.ContainsKey("SectionCode"))
                    configs.Add("SectionCode", config90);
                if (!configs.ContainsKey("BranchName"))
                    configs.Add("BranchName", config90);
                if (!configs.ContainsKey("OrgStructureName"))
                    configs.Add("OrgStructureName", config90);
                if (!configs.ContainsKey("TeamName"))
                    configs.Add("TeamName", config90);
                if (!configs.ContainsKey("SectionName"))
                    configs.Add("SectionName", config90);

                var config110 = new Dictionary<string, object>();
                config110.Add("width", 110);
                if (!configs.ContainsKey("BranchCode"))
                    configs.Add("BranchCode", config110);
                if (!configs.ContainsKey("OrgStructureCode"))
                    configs.Add("OrgStructureCode", config110);
                if (!configs.ContainsKey("JobtitleCode"))
                    configs.Add("JobtitleCode", config110);
                if (!configs.ContainsKey("PositionCode"))
                    configs.Add("PositionCode", config110);
                //configs.Add("DateExport", config110);
                //configs.Add("DateFrom", config110);
                //configs.Add("DateTo", config110);
                if (!configs.ContainsKey("UserExport"))
                    configs.Add("UserExport", config110);
                if (!configs.ContainsKey("DateExport"))
                    configs.Add("DateExport", configdate);
                if (!configs.ContainsKey("DateFrom"))
                    configs.Add("DateFrom", configdate);
                if (!configs.ContainsKey("DateTo"))
                    configs.Add("DateTo", configdate);

                return table.ConfigTable(configs);
            }
        }
Esempio n. 10
0
        /// <summary> Lấy JobName theo cong thức bên chế độ lương </summary>
        /// <param name="hdtJobMoney"></param>
        /// <param name="cat_SalaryClasses"></param>
        /// <param name="hdtJobGroups"></param>
        /// <param name="hreHdtJobProfile"></param>
        /// <param name="profile"></param>
        /// <param name="orgStructures"></param>
        /// <param name="orgTypes"></param>
        /// <param name="jobTitleName"></param>
        /// <param name="gradePayroll"></param>
        /// <param name="result"></param>
        /// <param name="listElementFormulaInDB"></param>
        private static void GetJobNameByFomular(double hdtJobMoney, List<Cat_SalaryClass> cat_SalaryClasses, List<Cat_HDTJobGroup> hdtJobGroups, Hre_HDTJob hreHdtJobProfile, Hre_ProfileEntity profile, List<Cat_OrgStructure> orgStructures, List<Cat_OrgStructureType> orgTypes, string jobTitleName, Cat_GradePayroll gradePayroll, out FormulaHelper.FormulaHelperModel result, List<Cat_Element> listElementFormulaInDB, out string hdtJobGroupCode)
        {
            /*
            *  Goal(Lấy JobName theo cong thức bên chế độ lương)
            *  Steps :
            *      Step1  :  Lấy giá trị của các phần tử 
            *      Step2  :  Thiết lập các phần tử (INS_JOBNAME_HDTJOBMONEY,INS_JOBNAME_NAMEOFRANK,INS_JOBNAME_HDTGROUPNAME,INS_JOBNAME_ORGSTRUCTURENAME,INS_JOBNAME_JOBTITLE)
            *      Step3  :  ParseFormula cho cot FormulaJobNameIns trong ds chế độ lương
            *      Step4  :  Note: rieng phần tử INS_JOBNAME_JOBTITLE  (nếu khac honda sẽ chỉ su dụng phần tử này)
            */

            var listElementFormula = new List<ElementFormula>();
            var item = new ElementFormula();

            #region Lấy giá trị của các phần tử
            var hdtGroupName = string.Empty;
            var nameOfRank = string.Empty;
            var orgName = string.Empty;

            #region Name of rank
            var salaryClass = cat_SalaryClasses.Where(p => profile != null && profile.SalaryClassID.HasValue && p.ID == profile.SalaryClassID).FirstOrDefault();
            if (salaryClass != null)
            {
                nameOfRank = salaryClass.AbilityTitleVNI + " ";
            }
            #endregion

            #region HdtJobGroup
            var hdtJobGroup = hdtJobGroups.Where(p => hreHdtJobProfile != null && p.ID == hreHdtJobProfile.HDTJobGroupID).FirstOrDefault();
            hdtJobGroupCode = string.Empty;
            if (hdtJobGroup != null)
            {
                hdtGroupName = hdtJobGroup.HDTJobGroupName;
                hdtJobGroupCode = hdtJobGroup.Code;
            }
            #endregion

            #region OrgStructure Name (tên tiếng Việt)
            var org = LibraryService.GetNearestParent(profile.OrgStructureID, OrgUnit.E_DEPARTMENT, orgStructures, orgTypes);

            if (org != null)
            {
                orgName = org.OrgStructureNameEN;
            }
            #endregion

            #endregion

            #region Thiết lập phần tử lấy jobName
            //lấy jobName
            string fomular = (new InsuranceServices()).FomularReplace(gradePayroll.FormulaJobNameIns, listElementFormulaInDB);
            gradePayroll.FormulaJobNameIns = fomular;
            if (gradePayroll.FormulaJobNameIns != null)
            {
                if (gradePayroll.FormulaJobNameIns.Contains(InsuranceElement.INS_JOBNAME_HDTJOBMONEY.ToString()))
                {
                    item = new ElementFormula(InsuranceElement.INS_JOBNAME_HDTJOBMONEY.ToString(), hdtJobMoney, 0);
                    listElementFormula.Add(item);
                }
                if (gradePayroll.FormulaJobNameIns.Contains(InsuranceElement.INS_JOBNAME_NAMEOFRANK.ToString()))
                {
                    item = new ElementFormula(InsuranceElement.INS_JOBNAME_NAMEOFRANK.ToString(), nameOfRank, 0);
                    listElementFormula.Add(item);
                }
                if (gradePayroll.FormulaJobNameIns.Contains(InsuranceElement.INS_JOBNAME_HDTGROUPNAME.ToString()))
                {
                    item = new ElementFormula(InsuranceElement.INS_JOBNAME_HDTGROUPNAME.ToString(), hdtGroupName, 0);
                    listElementFormula.Add(item);
                }
                if (gradePayroll.FormulaJobNameIns.Contains(InsuranceElement.INS_JOBNAME_ORGSTRUCTURENAME.ToString()))
                {
                    item = new ElementFormula(InsuranceElement.INS_JOBNAME_ORGSTRUCTURENAME.ToString(), orgName, 0);
                    listElementFormula.Add(item);
                }
                if (gradePayroll.FormulaJobNameIns.Contains(InsuranceElement.INS_JOBNAME_JOBTITLE.ToString()))
                {
                    item = new ElementFormula(InsuranceElement.INS_JOBNAME_JOBTITLE.ToString(), jobTitleName, 0);
                    listElementFormula.Add(item);
                }

                result = FormulaHelper.ParseFormula(fomular.Replace("[", "").Replace("]", ""), listElementFormula.Distinct().ToList());
            }
            else
            {
                result = new FormulaHelper.FormulaHelperModel();
                result.Value = string.Empty;
            }
            #endregion
        }
Esempio n. 11
0
        private int ComputeAttendance(IUnitOfWork unitOfWork, Guid userID, DateTime monthYear, Guid cutOffDurationID, DateTime attendanceFrom,
            DateTime attendanceTo, Hre_ProfileEntity profile, Cat_GradeAttendance gradeCfg, List<Cat_Shift> listShift, List<Att_AnnualDetail> listAnnualDetailByProfile,
            List<Hre_HDTJob> listHDTJobByProfile, List<Att_LeaveDayEntity> listLeaveDayByProfile, List<Cat_LeaveDayType> listLeaveDayType,
            List<Att_OvertimeEntity> listOvertimeByProfile, List<Cat_OvertimeType> listOvertimeType, List<Att_PregnancyEntity> listPregnancyByProfile,
            List<Cat_LateEarlyRule> listLateEarlyRule, List<Att_Workday> listWorkDayByProfile, List<Att_AttendanceTableEntity> listPreAttendanceTableByProfile,
            List<Att_TimeOffInLieuEntity> listTimeOffInLieuByProfile, Sys_AllSetting notAutoRegHolidayLeave, Sys_AllSetting otholidayscompute400,
            Sys_AllSetting missTAM_LeaveType, Dictionary<DateTime, List<Guid?>> listMonthShiftID, List<Cat_DayOff> listHoliday)
        {
            Guid profileID = profile.ID;

            if (gradeCfg == null || profile == null)
            {
                return 0;
            }

            DateTime midCutOffDate = attendanceTo;
            bool isMidCutOffDay = false;

            #region Tạo Att_AttendanceTable theo khoảng thời gian

            Att_AttendanceTable attendanceTable = new Att_AttendanceTable();
            unitOfWork.AddObject(typeof(Att_AttendanceTable), attendanceTable);
            attendanceTable.Status = AttendanceTableStatus.E_WAITING.ToString();
            attendanceTable.ID = Guid.NewGuid();
            attendanceTable.ProfileID = profileID;
            attendanceTable.MonthYear = monthYear;
            attendanceTable.DateStart = attendanceFrom;
            attendanceTable.DateEnd = attendanceTo;

            double anlDayTaken = 0D;
            double sickDayTaken = 0D;
            double coBeginPeriod = 0D;
            double coEndPeriod = 0D;

            if (cutOffDurationID != Guid.Empty)
            {
                attendanceTable.CutOffDurationID = cutOffDurationID;
            }

            //Tính công đến ngày cấu hình trong grade, những ngày sau mặc định full công - Khách hàng CPG
            if (gradeCfg != null && gradeCfg.IsMonthlyMidCutOff == true && gradeCfg.MidCutOffDay > 0)
            {
                if (!profile.DateQuit.HasValue || profile.DateQuit > attendanceTo)
                {
                    midCutOffDate = new DateTime(monthYear.Year,
                        monthYear.Month, gradeCfg.MidCutOffDay.Value);

                    //Luôn tạo một dòng Ứng công lúc tính công, kô cần biết có nghỉ không
                    Att_AdvanceTableItem advanceTableItem = new Att_AdvanceTableItem();
                    advanceTableItem.Att_AttendanceTable = attendanceTable;
                    advanceTableItem.DateFrom = midCutOffDate.AddDays(1);
                    advanceTableItem.DateTo = attendanceTo;
                    isMidCutOffDay = true;
                }
            }

            #endregion

            #region Tạo Att_AttendanceTableItem theo khoảng thời gian

            List<Att_AttendanceTableItem> listAttendanceTableItemByProfile = new List<Att_AttendanceTableItem>();

            for (DateTime date = attendanceFrom.Date; date <= attendanceTo; date = date.AddDays(1))
            {
                var workdayByProfile = listWorkDayByProfile.Where(d =>
                    d.WorkDate.Date == date).FirstOrDefault();

                Guid? shiftID1 = Guid.Empty;
                Guid? shiftID2 = Guid.Empty;

                var shiftByDate = listMonthShiftID.Where(d => d.Key.Date == date).Select(d => d.Value).FirstOrDefault();

                if (shiftByDate != null)
                {
                    if (shiftByDate.Count() > 0)
                    {
                        shiftID1 = shiftByDate[0];
                    }

                    if (shiftByDate.Count() > 1)
                    {
                        shiftID2 = shiftByDate[1];
                    }
                }

                if (workdayByProfile == null && gradeCfg.EDType == PayrollComputeMethod.E_SUBTRACT.ToString())
                {
                    if (shiftID1.HasValue && shiftID1 != Guid.Empty)
                    {
                        workdayByProfile = new Att_Workday
                        {
                            ShiftID = shiftID1,
                            ShiftApprove = shiftID1,
                            ShiftActual = shiftID1,
                            WorkDate = date
                        };

                        if (shiftID2.HasValue && shiftID2 != Guid.Empty)
                        {
                            workdayByProfile.Shift2ID = shiftID2;
                            workdayByProfile.ShiftApprove2 = shiftID2;
                            workdayByProfile.ShiftActual2 = shiftID2;
                        }

                        if (listHoliday.Any(d => d.DateOff.Date == date))
                        {
                            workdayByProfile.Type = WorkdayType.E_HOLIDAY.ToString();
                        }
                    }
                }

                Att_AttendanceTableItem attendanceTableItem = new Att_AttendanceTableItem();
                listAttendanceTableItemByProfile.Add(attendanceTableItem);
                attendanceTableItem.ID = Guid.NewGuid();
                attendanceTableItem.Att_AttendanceTable = attendanceTable;
                attendanceTableItem.DutyCode = DutyCode.E_OFF.ToString();
                attendanceTableItem.WorkDate = date;

                double nightDuration = 0F;
                double workDuration = 0F;

                attendanceTableItem.WorkPaidHours = 0;
                attendanceTableItem.PaidLeaveHours = 0;
                attendanceTableItem.UnpaidLeaveHours = 0;
                attendanceTableItem.LateEarlyMinutes = 0;
                attendanceTableItem.LateInMinutes = 0;
                attendanceTableItem.EarlyOutMinutes = 0;
                attendanceTableItem.LeaveHours = 0;
                attendanceTableItem.LeaveDays = 0;
                attendanceTableItem.WorkHourFirstHaftShift = 0;
                attendanceTableItem.WorkHourLastHaftShift = 0;

                if (workdayByProfile != null)
                {
                    attendanceTableItem.MissInOutReasonID = workdayByProfile.MissInOutReason;
                    attendanceTableItem.FirstInTime = workdayByProfile.FirstInTime;
                    attendanceTableItem.LastOutTime = workdayByProfile.LastOutTime;
                    attendanceTableItem.RootInTime = workdayByProfile.FirstInTime;
                    attendanceTableItem.RootOutTime = workdayByProfile.LastOutTime;
                    attendanceTableItem.ShiftID = workdayByProfile.ShiftID;
                    attendanceTableItem.Shift2ID = workdayByProfile.Shift2ID;

                    List<DateTime?> listInTime = new List<DateTime?>();
                    List<DateTime?> listOutTime = new List<DateTime?>();

                    listInTime.Add(workdayByProfile.InTime1);
                    listInTime.Add(workdayByProfile.InTime2);
                    listInTime.Add(workdayByProfile.InTime3);
                    listInTime.Add(workdayByProfile.InTime4);

                    listOutTime.Add(workdayByProfile.OutTime1);
                    listOutTime.Add(workdayByProfile.OutTime2);
                    listOutTime.Add(workdayByProfile.OutTime3);
                    listOutTime.Add(workdayByProfile.OutTime4);

                    attendanceTableItem.FirstInTime = listInTime.Where(d => d.HasValue).OrderBy(d => d).FirstOrDefault();
                    attendanceTableItem.LastOutTime = listOutTime.Where(d => d.HasValue).OrderBy(d => d).LastOrDefault();

                    if (workdayByProfile.ShiftApprove.HasValue)
                    {
                        attendanceTableItem.ShiftID = workdayByProfile.ShiftApprove.Value;
                    }

                    if (workdayByProfile.ShiftApprove2.HasValue)
                    {
                        attendanceTableItem.Shift2ID = workdayByProfile.ShiftApprove2.Value;
                    }

                    if (gradeCfg.AttendanceMethod == AttendanceMethod.E_FULL.ToString())
                    {
                        if (listMonthShiftID.Any(d => d.Key.Date == date))
                        {
                            //Bao.Tran: khi không kiểm tra vào ra thì ưu tiên ca đã tạo trong lịch làm việc
                            if (shiftID1 != Guid.Empty)
                            {
                                attendanceTableItem.ShiftID = shiftID1;
                            }

                            if (shiftID2 != Guid.Empty)
                            {
                                attendanceTableItem.Shift2ID = shiftID2;
                            }
                        }

                        //Bao.Tran: yêu cầu nếu công ko kiểm tra in/out thì không lấy in/out 
                        attendanceTableItem.FirstInTime = null;
                        attendanceTableItem.LastOutTime = null;

                        //comment code này do ảnh hưởng task 0046036 : ko tính được ngày nghỉ lễ
                        ////Bao.Tran: do khi THNC cũ, Nếu ko bỏ type thì nó sẽ tính ngày công trên là holiday  (attendanceTableItem.IsHoliday = true;)
                        //workdayByProfile.Type = WorkdayType.E_NORMAL.ToString();
                    }

                    //kiểm tra ngày làm việc có Lịch làm việc hay ko?
                    if (attendanceTableItem.ShiftID != null && workdayByProfile.FirstInTime != null && workdayByProfile.LastOutTime != null)
                    {
                        #region Kiểm tra HDTJob

                        var listHDTJobByProfileByDate = listHDTJobByProfile.Where(d => (d.DateFrom.Value.Date <= date && d.DateTo == null)
                            || (d.DateTo != null && d.DateFrom.Value.Date <= date && d.DateTo.Value.Date >= date)).ToList();

                        foreach (var HDTJobByProfile in listHDTJobByProfileByDate)
                        {
                            if (HDTJobByProfile != null)
                            {
                                attendanceTableItem.HDTJobType = HDTJobByProfile.Type;
                            }
                        }

                        #endregion
                    }
                }

                var shiftByProfile1 = listShift.Where(d => d.ID == attendanceTableItem.ShiftID).FirstOrDefault();
                var shiftByProfile2 = listShift.Where(d => d.ID == attendanceTableItem.Shift2ID).FirstOrDefault();

                if (shiftByProfile1 != null)
                {
                    attendanceTableItem.Cat_Shift = shiftByProfile1;
                    attendanceTableItem.AvailableHours = shiftByProfile1.udAvailableHours;
                }

                if (shiftByProfile2 != null)
                {
                    attendanceTableItem.Cat_Shift1 = shiftByProfile2;
                }

                if ((workdayByProfile != null && workdayByProfile.Type == WorkdayType.E_HOLIDAY.ToString())
                    || (attendanceTableItem.ShiftID.HasValue && attendanceTableItem.ShiftID != Guid.Empty))
                {
                    //Ngày đang xét là ngày làm việc bình thường
                    attendanceTableItem.DutyCode = DutyCode.E_ON.ToString();

                    if (workdayByProfile.Type == WorkdayType.E_HOLIDAY.ToString())
                    {
                        attendanceTableItem.IsHoliday = true;
                    }
                }
                else
                {
                    //Ngày đang xét không phải là ngày làm việc bình thường
                    attendanceTableItem.DutyCode = DutyCode.E_OFF.ToString();
                }

                #region Kiểm tra ngày nghỉ - leaveday

                if (attendanceTableItem.DutyCode != DutyCode.E_OFF.ToString())
                {
                    var listLeaveDayByProfileByDate = listLeaveDayByProfile.Where(d =>
                        d.DateStart.Date <= date && d.DateEnd.Date >= date).ToList();

                    foreach (var leaveDayByProfile in listLeaveDayByProfileByDate)
                    {
                        if (leaveDayByProfile != null)
                        {
                            double leaveHours = 0D;
                            double leaveDays = 0D;

                            var leaveDayType = listLeaveDayType.Where(d => d.ID ==
                                leaveDayByProfile.LeaveDayTypeID).FirstOrDefault();

                            var standardWorkHours = attendanceTableItem.AvailableHours;

                            if (leaveDayByProfile.DurationType == LeaveDayDurationType.E_FULLSHIFT.ToString())
                            {
                                //Lấy giờ nghỉ của ngày đang xét dựa vào ca làm việc
                                leaveHours = standardWorkHours;
                                leaveDays = 1;//Nghỉ full shift
                            }
                            else
                            {
                                leaveHours = leaveDayByProfile.LeaveHours.GetDouble();
                                leaveDays = leaveDayByProfile.LeaveDays.GetDouble();
                            }

                            leaveHours = leaveHours > standardWorkHours ? standardWorkHours : leaveHours;
                            leaveDays = leaveDays > 1 ? 1 : leaveDays;//Tối đa là nghỉ 1 ngày

                            if (!attendanceTableItem.LeaveTypeID.HasValue)
                            {
                                attendanceTableItem.LeaveTypeID = leaveDayByProfile.LeaveDayTypeID;
                                attendanceTableItem.Cat_LeaveDayType = leaveDayType;

                                attendanceTableItem.LeaveHours = leaveHours;
                                attendanceTableItem.LeaveDays = leaveDays;
                            }
                            else if (!attendanceTableItem.ExtraLeaveTypeID.HasValue)
                            {
                                attendanceTableItem.ExtraLeaveTypeID = leaveDayByProfile.LeaveDayTypeID;
                                attendanceTableItem.Cat_LeaveDayType1 = leaveDayType;

                                attendanceTableItem.ExtraLeaveHours = leaveHours;
                                attendanceTableItem.ExtraLeaveDays = leaveDays;
                            }

                            if (leaveDayType != null && leaveDays > 0)
                            {
                                if (leaveDayType.Code == LeavedayTypeCode.ANL.ToString())
                                {
                                    anlDayTaken += leaveDays;
                                }
                                if (leaveDayType.Code == LeavedayTypeCode.SICK.ToString())
                                {
                                    sickDayTaken += leaveDays;
                                }
                            }
                        }
                    }
                }

                #endregion

                #region Kiểm tra làm thêm - overtime

                if (gradeCfg != null && gradeCfg.IsReceiveOvertimeBonus.Get_Boolean())
                {
                    var listOvertimeByProfileByDate = listOvertimeByProfile.Where(d =>
                        d.WorkDate.Date == date).ToList();

                    foreach (var overtime in listOvertimeByProfileByDate)
                    {
                        if (overtime != null)
                        {
                            double overtimeHours = overtime.ConfirmHours;
                            string overTimeStatus = OverTimeStatus.E_APPROVED.ToString();

                            if (overTimeStatus == OverTimeStatus.E_APPROVED.ToString())
                            {
                                overtimeHours = overtime.ApproveHours.GetDouble();
                            }
                            else if (overTimeStatus == OverTimeStatus.E_CONFIRM.ToString())
                            {
                                overtimeHours = overtime.ConfirmHours;
                            }

                            if (!attendanceTableItem.OvertimeTypeID.HasValue)
                            {
                                attendanceTableItem.OvertimeTypeID = overtime.OvertimeTypeID;
                                attendanceTableItem.Cat_OvertimeType = listOvertimeType.Where(s => s.ID == overtime.OvertimeTypeID).FirstOrDefault();
                                attendanceTableItem.OvertimeDurationType = overtime.DurationType;
                                attendanceTableItem.OvertimeRegisterHours = overtime.RegisterHours;
                                attendanceTableItem.OvertimeHours = overtimeHours;
                            }
                            else if (!attendanceTableItem.ExtraOvertimeTypeID.HasValue)
                            {
                                attendanceTableItem.ExtraOvertimeTypeID = overtime.OvertimeTypeID;
                                attendanceTableItem.Cat_OvertimeType1 = listOvertimeType.Where(s => s.ID == overtime.OvertimeTypeID).FirstOrDefault();
                                attendanceTableItem.ExtraOvertimeDurationType = overtime.DurationType;
                                attendanceTableItem.ExtraOvertimeRegisterHours = overtime.RegisterHours;
                                attendanceTableItem.ExtraOvertimeHours = overtimeHours;
                            }
                            else if (!attendanceTableItem.ExtraOvertimeType2ID.HasValue)
                            {
                                attendanceTableItem.ExtraOvertimeType2ID = overtime.OvertimeTypeID;
                                attendanceTableItem.Cat_OvertimeType2 = listOvertimeType.Where(s => s.ID == overtime.OvertimeTypeID).FirstOrDefault();
                                attendanceTableItem.ExtraOvertimeDurationType2 = overtime.DurationType;
                                attendanceTableItem.ExtraOvertimeRegisterHours2 = overtime.RegisterHours;
                                attendanceTableItem.ExtraOvertimeHours2 = overtimeHours;
                            }
                            else if (!attendanceTableItem.ExtraOvertimeType3ID.HasValue)
                            {
                                attendanceTableItem.ExtraOvertimeType3ID = overtime.OvertimeTypeID;
                                attendanceTableItem.Cat_OvertimeType3 = listOvertimeType.Where(s => s.ID == overtime.OvertimeTypeID).FirstOrDefault();
                                attendanceTableItem.ExtraOvertimeDurationType3 = overtime.DurationType;
                                attendanceTableItem.ExtraOvertimeRegisterHours3 = overtime.RegisterHours;
                                attendanceTableItem.ExtraOvertimeHours3 = overtimeHours;
                            }
                        }
                    }
                }

                #endregion

                #region Kiểm tra có thai sản không

                var pregnancyByProfile = listPregnancyByProfile.Where(d =>
                    date >= d.DateStart && date <= d.DateEnd).FirstOrDefault();

                if (pregnancyByProfile != null)
                {
                    attendanceTableItem.IsHavingPregTreatment = true;
                }

                #endregion

                #region Nhân viên đã nghỉ hoặc chưa đi làm

                if ((profile.DateQuit.HasValue && profile.DateQuit.Value.Date <= date.Date)
                   || (profile.DateHire.HasValue && profile.DateHire.Value.Date > date.Date))
                {
                    if (attendanceTableItem.DutyCode == DutyCode.E_ON.ToString())
                    {
                        if (profile.DateHire.HasValue && profile.DateHire.Value.Date > date.Date)
                        {
                            if (shiftByProfile1 != null)
                            {
                                attendanceTableItem.udNotHiredHours = shiftByProfile1.WorkHours.GetDouble();
                            }
                            else
                            {
                                attendanceTableItem.udNotHiredHours = attendanceTableItem.udStandardWorkHours;
                            }

                            if (shiftByProfile2 != null)
                            {
                                attendanceTableItem.udNotHiredHours += shiftByProfile2.WorkHours.GetDouble();
                            }
                        }

                        if (profile.DateQuit.HasValue && profile.DateQuit.Value.Date <= date.Date)
                        {
                            if (shiftByProfile1 != null)
                            {
                                attendanceTableItem.udTerminatedHours = shiftByProfile1.WorkHours.GetDouble();
                            }
                            else
                            {
                                attendanceTableItem.udTerminatedHours = attendanceTableItem.udStandardWorkHours;
                            }

                            if (shiftByProfile2 != null)
                            {
                                attendanceTableItem.udTerminatedHours += shiftByProfile2.WorkHours.GetDouble();
                            }
                        }
                    }

                    attendanceTableItem.Cat_LeaveDayType = null;
                    continue;
                }

                #endregion

                #region Loại ngày nghỉ là ngày làm việc

                if (attendanceTableItem.Cat_LeaveDayType != null)
                {
                    //Trường hợp ngày nghỉ tính như ngày đi làm => không tính nghỉ
                    if (attendanceTableItem.Cat_LeaveDayType.IsWorkDay)
                    {
                        attendanceTableItem.WorkHours += attendanceTableItem.LeaveHours;
                        attendanceTableItem.WorkPaidHours += attendanceTableItem.LeaveHours;

                        attendanceTableItem.LeaveWorkDayHour = attendanceTableItem.LeaveHours;
                        attendanceTableItem.LeaveWorkDayDays = attendanceTableItem.LeaveHours / attendanceTableItem.udStandardWorkHours;
                        attendanceTableItem.Cat_LeaveDayType2 = attendanceTableItem.Cat_LeaveDayType;

                        attendanceTableItem.Cat_LeaveDayType = null;
                        attendanceTableItem.LeaveHours = 0;
                        attendanceTableItem.LeaveDays = 0;
                    }
                    else
                    {
                        attendanceTableItem.PaidLeaveHours += attendanceTableItem.LeaveHours * attendanceTableItem.Cat_LeaveDayType.PaidRate;
                        attendanceTableItem.UnpaidLeaveHours += attendanceTableItem.LeaveHours * (1 - attendanceTableItem.Cat_LeaveDayType.PaidRate);

                        attendanceTableItem.PaidLeaveDays = attendanceTableItem.PaidLeaveHours / attendanceTableItem.udStandardWorkHours;
                        attendanceTableItem.UnpaidLeaveDays = attendanceTableItem.UnpaidLeaveHours / attendanceTableItem.udStandardWorkHours;
                    }
                }

                if (attendanceTableItem.Cat_LeaveDayType1 != null)
                {
                    if (attendanceTableItem.Cat_LeaveDayType1.IsWorkDay)
                    {
                        attendanceTableItem.WorkHours += attendanceTableItem.ExtraLeaveHours;
                        attendanceTableItem.WorkPaidHours += attendanceTableItem.ExtraLeaveHours;
                        attendanceTableItem.Cat_LeaveDayType1 = null;
                        attendanceTableItem.ExtraLeaveHours = 0;
                    }
                    else
                    {
                        attendanceTableItem.PaidLeaveHours += attendanceTableItem.ExtraLeaveHours * attendanceTableItem.Cat_LeaveDayType1.PaidRate;
                        attendanceTableItem.UnpaidLeaveHours += attendanceTableItem.ExtraLeaveHours * (1 - attendanceTableItem.Cat_LeaveDayType1.PaidRate);
                    }
                }

                #endregion

                if (attendanceTableItem.DutyCode == DutyCode.E_ON.ToString())
                {
                    #region IsHavingPregTreatment

                    if (attendanceTableItem.IsHavingPregTreatment)
                    {
                        if ((attendanceTableItem.WorkPaidHours + attendanceTableItem.PaidLeaveHours) > attendanceTableItem.AvailableHours)
                        {
                            attendanceTableItem.WorkPaidHours = attendanceTableItem.AvailableHours - attendanceTableItem.PaidLeaveHours;
                        }
                        else
                        {
                            attendanceTableItem.WorkPaidHours = attendanceTableItem.WorkPaidHours;
                        }
                    }

                    #endregion

                    #region LateEarlyMinutes

                    attendanceTableItem.LateEarlyMinutes = (int)workdayByProfile.LateEarlyDuration.GetDouble();
                    attendanceTableItem.RealLateEarlyMinutes = attendanceTableItem.LateEarlyMinutes;

                    #endregion

                    #region Tính số giờ đi làm

                    if (workdayByProfile != null && shiftByProfile1 != null)
                    {
                        DateTime timeShiftStart1 = workdayByProfile.WorkDate.Date.Add(shiftByProfile1.InTime.TimeOfDay);
                        DateTime timeShiftEnd1 = timeShiftStart1.AddHours(shiftByProfile1.CoOut);

                        //Thời gian bắt đầu và kết thúc nghỉ giữa ca - dùng cho tính toán
                        DateTime timeShiftBreakIn1 = timeShiftStart1.AddHours(shiftByProfile1.CoBreakIn);
                        DateTime timeShiftBreakOut1 = timeShiftStart1.AddHours(shiftByProfile1.CoBreakOut);

                        workDuration = GetDuration(workdayByProfile, timeShiftStart1, timeShiftEnd1,
                            timeShiftBreakIn1, timeShiftBreakOut1, shiftByProfile1.InOutDynamic);

                        #region Tính số giờ làm ca đêm

                        if (shiftByProfile1.IsNightShift)
                        {
                            DateTime nightTimeStart = workdayByProfile.WorkDate.Date.AddHours(22);
                            DateTime nightTimeEnd = workdayByProfile.WorkDate.Date.AddDays(1).AddHours(6);

                            nightTimeStart = workdayByProfile.WorkDate.Date.Add(shiftByProfile1.NightTimeStart.Value.TimeOfDay);
                            nightTimeEnd = workdayByProfile.WorkDate.Date.Add(shiftByProfile1.NightTimeEnd.Value.TimeOfDay);
                            nightTimeEnd = nightTimeStart > nightTimeEnd ? nightTimeEnd.AddDays(1) : nightTimeEnd;

                            //Truong hop nghi giua ca nam trong khoang bat dau ca dem
                            nightDuration = GetDuration(workdayByProfile, nightTimeStart, nightTimeEnd,
                                timeShiftBreakIn1, timeShiftBreakOut1, shiftByProfile1.InOutDynamic);
                        }

                        #endregion
                    }

                    if (workdayByProfile != null && shiftByProfile2 != null)
                    {
                        DateTime timeShiftStart2 = workdayByProfile.WorkDate.Date.Add(shiftByProfile2.InTime.TimeOfDay);
                        DateTime timeShiftEnd2 = timeShiftStart2.AddHours(shiftByProfile2.CoOut);

                        //Thời gian bắt đầu và kết thúc nghỉ giữa ca - dùng cho tính toán
                        DateTime timeShiftBreakIn2 = timeShiftStart2.AddHours(shiftByProfile2.CoBreakIn);
                        DateTime timeShiftBreakOut2 = timeShiftStart2.AddHours(shiftByProfile2.CoBreakOut);

                        workDuration += GetDuration(workdayByProfile, timeShiftStart2, timeShiftEnd2,
                            timeShiftBreakIn2, timeShiftBreakOut2, shiftByProfile2.InOutDynamic);

                        #region Tính số giờ làm ca đêm

                        if (shiftByProfile2.IsNightShift)
                        {
                            DateTime nightTimeStart = workdayByProfile.WorkDate.Date.AddHours(22);
                            DateTime nightTimeEnd = workdayByProfile.WorkDate.Date.AddDays(1).AddHours(6);

                            nightTimeStart = workdayByProfile.WorkDate.Date.Add(shiftByProfile2.NightTimeStart.Value.TimeOfDay);
                            nightTimeEnd = workdayByProfile.WorkDate.Date.Add(shiftByProfile2.NightTimeEnd.Value.TimeOfDay);
                            nightTimeEnd = nightTimeStart > nightTimeEnd ? nightTimeEnd.AddDays(1) : nightTimeEnd;

                            //Truong hop nghi giua ca nam trong khoang bat dau ca dem
                            nightDuration = GetDuration(workdayByProfile, nightTimeStart, nightTimeEnd,
                                timeShiftBreakIn2, timeShiftBreakOut2, shiftByProfile2.InOutDynamic);
                        }

                        #endregion
                    }

                    attendanceTableItem.NightShiftHours = (nightDuration / 60);//lưu số giờ 
                    attendanceTableItem.WorkPaidHours = (workDuration / 60);//lưu số giờ 
                    attendanceTableItem.WorkHours = (workDuration / 60);//lưu số giờ 

                    attendanceTableItem.WorkPaidHours = attendanceTableItem.WorkPaidHours < 0 ? 0 : attendanceTableItem.WorkPaidHours;
                    attendanceTableItem.WorkPaidHours = attendanceTableItem.WorkPaidHours > attendanceTableItem.AvailableHours
                        ? attendanceTableItem.AvailableHours : attendanceTableItem.WorkPaidHours;

                    #endregion

                    if (gradeCfg.AttendanceMethod == AttendanceMethod.E_FULL.ToString())
                    {
                        #region gradeCfg.AttendanceMethod = E_FULL

                        if (shiftByProfile1 != null && shiftByProfile1.IsNightShift == true)
                        {
                            if (shiftByProfile1.NightTimeEnd != null && shiftByProfile1.NightTimeStart != null)
                            {
                                DateTime dateStartNightShift = shiftByProfile1.NightTimeStart.Value;
                                DateTime dateEndNightShift = shiftByProfile1.NightTimeEnd.Value;

                                if (dateStartNightShift > dateEndNightShift)
                                {
                                    dateEndNightShift = dateEndNightShift.AddDays(1);
                                }

                                attendanceTableItem.NightShiftHours = dateEndNightShift.Subtract(dateStartNightShift).TotalHours;
                            }
                            else
                            {
                                attendanceTableItem.NightShiftHours = shiftByProfile1.WorkHours ?? 0;
                            }
                        }
                        else if (shiftByProfile2 != null && shiftByProfile2.IsNightShift == true)
                        {
                            if (shiftByProfile2.NightTimeEnd != null && shiftByProfile2.NightTimeStart != null)
                            {
                                DateTime dateStartNightShift = shiftByProfile2.NightTimeStart.Value;
                                DateTime dateEndNightShift = shiftByProfile2.NightTimeEnd.Value;

                                if (dateStartNightShift > dateEndNightShift)
                                {
                                    dateEndNightShift = dateEndNightShift.AddDays(1);
                                }

                                attendanceTableItem.NightShiftHours = dateEndNightShift.Subtract(dateStartNightShift).TotalHours;
                            }
                            else
                            {
                                attendanceTableItem.NightShiftHours = shiftByProfile2.WorkHours ?? 0;
                            }
                        }

                        if ((shiftByProfile1 != null && shiftByProfile1.IsNightShift == true)
                            || shiftByProfile2 != null && shiftByProfile2.IsNightShift == true)
                        {
                            if (attendanceTableItem.Cat_LeaveDayType != null)
                            {
                                double hourLeave = attendanceTableItem.LeaveHours + attendanceTableItem.PaidLeaveHours + attendanceTableItem.ExtraLeaveHours;
                                attendanceTableItem.NightShiftHours = attendanceTableItem.NightShiftHours - hourLeave;

                                if (attendanceTableItem.NightShiftHours < 0)
                                {
                                    attendanceTableItem.NightShiftHours = 0;
                                }
                            }
                        }

                        if (attendanceTableItem.IsHoliday)
                        {
                            attendanceTableItem.LeaveHours = attendanceTableItem.PaidLeaveHours = 0;
                            attendanceTableItem.WorkPaidHours = attendanceTableItem.LateEarlyMinutes = 0;
                            attendanceTableItem.UnpaidLeaveHours = attendanceTableItem.AvailableHours;

                            bool isNoLongerWorking = false;

                            if ((profile.DateHire.HasValue && attendanceTableItem.WorkDate < profile.DateHire.Value)
                                || (profile.DateQuit.HasValue && attendanceTableItem.WorkDate >= profile.DateQuit.Value))
                            {
                                isNoLongerWorking = true;
                            }

                            if (!attendanceTableItem.IsHavingPregTreatment && !isNoLongerWorking && (notAutoRegHolidayLeave == null
                                || notAutoRegHolidayLeave.Value1 != bool.TrueString))
                            {
                                attendanceTableItem.WorkPaidHours = 0;
                                attendanceTableItem.LateEarlyMinutes = 0;
                                attendanceTableItem.UnpaidLeaveHours = 0;

                                attendanceTableItem.LeaveHours = attendanceTableItem.AvailableHours;
                                attendanceTableItem.PaidLeaveHours = attendanceTableItem.AvailableHours;

                                attendanceTableItem.Cat_LeaveDayType = listLeaveDayType.Where(d =>
                                    d.Code == LeavedayTypeCode.HLD.ToString()).FirstOrDefault();
                            }
                        }

                        attendanceTableItem.WorkHours = 0;//Thời gian làm việc = 0
                        attendanceTableItem.WorkPaidHours = attendanceTableItem.AvailableHours
                            - attendanceTableItem.UnpaidLeaveHours - attendanceTableItem.PaidLeaveHours;

                        #endregion
                    }

                    #region Trường hợp tăng ca trong ngày lễ

                    if (attendanceTableItem.Cat_LeaveDayType != null && attendanceTableItem.Cat_LeaveDayType.Code == LeavedayTypeCode.HLD.ToString() &&
                        (otholidayscompute400 == null || otholidayscompute400.Value1 != bool.TrueString) && attendanceTableItem.Cat_OvertimeType != null)
                    {
                        var totalOvertimeHours = attendanceTableItem.OvertimeHours + attendanceTableItem.ExtraOvertimeHours
                            + attendanceTableItem.ExtraOvertimeHours2 + attendanceTableItem.ExtraOvertimeHours3;

                        if (gradeCfg.EDType == PayrollComputeMethod.E_SUBTRACT.ToString())
                        {
                            if (attendanceTableItem.AvailableHours > totalOvertimeHours)
                            {
                                attendanceTableItem.LeaveHours = attendanceTableItem.AvailableHours - totalOvertimeHours;
                                attendanceTableItem.ExtraLeaveHours = totalOvertimeHours;
                                attendanceTableItem.PaidLeaveHours = attendanceTableItem.LeaveHours;
                                attendanceTableItem.Cat_LeaveDayType1 = null;
                            }
                            else
                            {
                                attendanceTableItem.Cat_LeaveDayType = null;
                                attendanceTableItem.LeaveHours = attendanceTableItem.AvailableHours;
                                attendanceTableItem.PaidLeaveHours = 0;
                            }
                        }
                        else
                        {
                            if (attendanceTableItem.AvailableHours >= totalOvertimeHours)
                            {
                                attendanceTableItem.LeaveHours = attendanceTableItem.PaidLeaveHours =
                                    attendanceTableItem.AvailableHours - totalOvertimeHours;
                            }
                            else
                            {
                                attendanceTableItem.LeaveHours = attendanceTableItem.PaidLeaveHours = 0;
                            }
                        }

                        attendanceTableItem.WorkPaidHours = 0;
                    }

                    #endregion
                }

                unitOfWork.AddObject(typeof(Att_AttendanceTableItem), attendanceTableItem);
            }

            #endregion

            #region Tính toán lại phép năm và phép ốm trong kỳ

            var annualLeaveDetail = listAnnualDetailByProfile.Where(d => d.Type == AnnualLeaveDetailType.E_ANNUAL_LEAVE.ToString()).FirstOrDefault();
            var sickLeaveDetail = listAnnualDetailByProfile.Where(d => d.Type == AnnualLeaveDetailType.E_SICK_LEAVE.ToString()).FirstOrDefault();
            var preAttendanceTable = listPreAttendanceTableByProfile.Where(d => d.ProfileID == profileID).FirstOrDefault();

            attendanceTable.AnlDayTaken = anlDayTaken;
            attendanceTable.SickDayTaken = sickDayTaken;

            if (preAttendanceTable != null)
            {
                if (annualLeaveDetail != null && annualLeaveDetail.MonthYear.HasValue
                    && annualLeaveDetail.MonthYear.Value.Date == monthYear.Date)
                {
                    attendanceTable.AnlDayAdjacent = anlDayTaken;
                }
                else
                {
                    //VinhTran - 0030581 - AnlDayAdjacent là số ngày đã nghỉ tính tới đầu tháng đang tính công
                    attendanceTable.AnlDayAdjacent = preAttendanceTable.AnlDayAdjacent.GetDouble() + anlDayTaken;
                }

                if (sickLeaveDetail != null && sickLeaveDetail.MonthYear.HasValue
                    && sickLeaveDetail.MonthYear.Value.Date == monthYear.Date)
                {
                    attendanceTable.SickDayAdjacent = sickDayTaken;
                }
                else
                {
                    //VinhTran - 0030581 - AnlDayAdjacent là số ngày đã nghỉ tính tới đầu tháng đang tính công
                    attendanceTable.SickDayAdjacent = preAttendanceTable.SickDayAdjacent.GetDouble() + sickDayTaken;
                }
            }
            else
            {
                attendanceTable.AnlDayAdjacent = anlDayTaken;
                attendanceTable.SickDayAdjacent = sickDayTaken;
            }

            if (annualLeaveDetail != null && annualLeaveDetail.MonthYear.HasValue)
            {
                attendanceTable.TotalAnlDayAvailable = annualLeaveDetail.Available.Get_Double();
                attendanceTable.AnlDayAvailable = attendanceTable.TotalAnlDayAvailable.GetDouble() - attendanceTable.AnlDayAdjacent.GetDouble();
            }
            else if (preAttendanceTable != null)
            {
                attendanceTable.AnlDayAvailable = preAttendanceTable.AnlDayAvailable - attendanceTable.AnlDayTaken;
            }

            if (sickLeaveDetail != null && sickLeaveDetail.MonthYear.HasValue)
            {
                attendanceTable.TotalSickDayAvailable = sickLeaveDetail.Available.Get_Double();
                attendanceTable.SickDayAvailable = attendanceTable.TotalSickDayAvailable.GetDouble() - attendanceTable.SickDayAdjacent.GetDouble();
            }
            else if (preAttendanceTable != null)
            {
                //tháng 7: còn 13, liền kề 1, hiện tại 1 => tháng 8: liền kề 2, hiện tại 1, còn 12
                attendanceTable.SickDayAvailable = preAttendanceTable.SickDayAvailable.GetDouble() - attendanceTable.SickDayTaken.GetDouble();
            }

            #endregion

            #region Tính toán lại phép bù trong kỳ

            foreach (var leaveDayByProfile in listLeaveDayByProfile)
            {
                if (leaveDayByProfile != null)
                {
                    var dateStart = leaveDayByProfile.DateStart;
                    var dateEnd = leaveDayByProfile.DateEnd;

                    if (leaveDayByProfile.DateOvertimeOff.HasValue)
                    {
                        dateStart = leaveDayByProfile.DateOvertimeOff.Value;
                        dateEnd = leaveDayByProfile.DateOvertimeOff.Value;
                    }

                    for (DateTime date = dateStart.Date; date <= dateEnd; date = date.AddDays(1))
                    {
                        double leaveHours = 0D;
                        double leaveDays = 0D;
                        double standardWorkHours = 0;

                        var leaveDayType = listLeaveDayType.Where(d => d.ID == leaveDayByProfile.LeaveDayTypeID).FirstOrDefault();
                        var attendanceTableItem = attendanceTable.Att_AttendanceTableItem.Where(d => d.WorkDate == date).FirstOrDefault();
                        if (attendanceTableItem!=null)
                            standardWorkHours = attendanceTableItem.udStandardWorkHours;

                        if (leaveDayByProfile.DurationType == LeaveDayDurationType.E_FULLSHIFT.ToString())
                        {   
                            //Lấy giờ nghỉ của ngày đang xét dựa vào ca làm việc
                            leaveHours = standardWorkHours;
                            leaveDays = 1;//Nghỉ full shift
                        }
                        else
                        {
                            leaveHours = leaveDayByProfile.LeaveHours.GetDouble();
                            leaveDays = leaveDayByProfile.LeaveDays.GetDouble();
                        }

                        leaveHours = leaveHours > standardWorkHours ? standardWorkHours : leaveHours;
                        leaveDays = leaveDays > 1 ? 1 : leaveDays;//Tối đa là nghỉ 1 ngày

                        if (leaveDayType != null && leaveDays > 0)
                        {
                            if (leaveDayType.Code == LeavedayTypeCode.CPS.ToString()
                                || leaveDayType.Code == LeavedayTypeCode.OCPS.ToString())
                            {
                                if ((leaveDayByProfile.DateOvertimeOff.HasValue
                                    && leaveDayByProfile.DateStart > attendanceTo)
                                    || date > attendanceTo)
                                {
                                    //Nghỉ CO tháng sau => coEndPeriod
                                    coEndPeriod += leaveDays;
                                }
                                else if (date >= attendanceFrom && date <= attendanceTo)
                                {
                                    //Nghỉ CO trong tháng => coBeginPeriod
                                    coBeginPeriod += leaveDays;
                                }
                            }
                        }
                    }
                }
            }

            attendanceTable.COBeginPeriod = coBeginPeriod;
            attendanceTable.COEndPeriod = coEndPeriod;

            #endregion

            #region Cập nhật Att_AttendanceTable sau khi tính xong

            #region Sum type HDTJob
            var _type4 = attendanceTable.Att_AttendanceTableItem.Where(d => d.HDTJobType == EnumDropDown.HDTJobType.E_TYPE4.ToString());
            var _type5 = attendanceTable.Att_AttendanceTableItem.Where(d => d.HDTJobType == EnumDropDown.HDTJobType.E_TYPE5.ToString());
            attendanceTable.HDTJobType1 = EnumDropDown.HDTJobType.E_TYPE4.ToString();
            attendanceTable.HDTJobType2 = EnumDropDown.HDTJobType.E_TYPE5.ToString();
            attendanceTable.HDTJobDayCount1 = _type4 != null ? _type4.Count() : 0;
            attendanceTable.HDTJobDayCount2 = _type5 != null ? _type5.Count() : 0;

            #endregion

            attendanceTable.RealWorkDayCount = attendanceTable.Att_AttendanceTableItem.Where(d => d.udWorkHours > 0).Sum(d => (d.WorkPaidHours + d.LateEarlyMinutes / 60.0) / (d.udStandardWorkHours * d.udStandardWorkHours / d.udWorkHours));
            attendanceTable.NightShiftHours = attendanceTable.Att_AttendanceTableItem.Where(d => d.DutyCode == DutyCode.E_ON.ToString()).Sum(d => d.NightShiftHours);
            attendanceTable.OTNightShiftHours = attendanceTable.Att_AttendanceTableItem.Where(d => d.DutyCode == DutyCode.E_ON.ToString()).Sum(d => d.OTNightShiftHours.GetDouble());
            attendanceTable.LateEarlyDeductionHours += attendanceTable.Att_AttendanceTableItem.Sum(d => d.LateEarlyMinutes) / 60.0;
            attendanceTable.UnPaidLeave = attendanceTable.Att_AttendanceTableItem.Sum(d => d.UnpaidLeaveDays.GetDouble());
            attendanceTable.PaidLeaveDays = attendanceTable.Att_AttendanceTableItem.Sum(d => d.PaidLeaveDays.GetDouble());

            //Tính nghỉ bù
            attendanceTable.COBeginPeriod = coBeginPeriod;
            attendanceTable.COEndPeriod = coEndPeriod;

            //Tính số ngày công chuẩn
            int weekendDaysCount = attendanceTable.Att_AttendanceTableItem.Where(d => d.IsHoliday).Count();
            attendanceTable.StdWorkDayCount = GetStandardWorkDays(gradeCfg, listHoliday, listShift, listMonthShiftID, monthYear, attendanceFrom, attendanceTo);
            attendanceTable.StdWorkDayOTCount = GetOTStandardWorkDays(weekendDaysCount, gradeCfg, listHoliday, listShift, listMonthShiftID, monthYear, attendanceFrom, attendanceTo);

            //Tổng số ngày được trả lương của nhân viên đang xét => ngày thực tế
            attendanceTable.PaidWorkDayCount = attendanceTable.RealWorkDayCount;

            if (gradeCfg.EDType == PayrollComputeMethod.E_SUBTRACT.ToString())
            {
                //Số ngày công thực tế + số ngày nghỉ hưởng lương
                Double workAndPaidLeaveDays = attendanceTable.RealWorkDayCount;
                double unHiredDays = 0; double terminatedDays = 0;

                if (attendanceTable.Att_AttendanceTableItem.Count() > 0)
                {
                    workAndPaidLeaveDays += attendanceTable.Att_AttendanceTableItem.Sum(d =>
                        d.PaidLeaveHours / d.udStandardWorkHours);
                }

                //Nếu nhân viên không vào làm hoặc nghỉ việc trong tháng và số ngày công thực tế + số ngày nghỉ hưởng lương > số ngày công tối thiểu
                if (((profile.DateHire.HasValue && profile.DateHire.Value.Date < attendanceFrom) || workAndPaidLeaveDays > attendanceTable.StdWorkDayCount)
                    && ((!profile.DateQuit.HasValue || profile.DateQuit.Value.Date > attendanceTo) || workAndPaidLeaveDays > attendanceTable.StdWorkDayCount)
                    && workAndPaidLeaveDays >= gradeCfg.MinWorkDay.Value)
                {
                    //Tổng số ngày nghỉ loại 1 và loại 2 khi có trường hợp 1 ngày mà nghỉ 2 loại
                    Double totalLeaveDays = attendanceTable.Att_AttendanceTableItem.Sum(d =>
                       (d.LeaveHours + d.ExtraLeaveHours) / d.udStandardWorkHours);

                    if (isMidCutOffDay)
                    {
                        totalLeaveDays = attendanceTable.Att_AttendanceTableItem.Where(d => d.WorkDate <= midCutOffDate)
                            .Sum(d => d.LeaveHours + d.ExtraLeaveHours / d.udStandardWorkHours);//Số ngày nghỉ không ứng công
                    }

                    //Cộng thêm số ngày chưa làm việc - trường hợp làm nửa ca
                    totalLeaveDays += attendanceTable.Att_AttendanceTableItem.Sum(d =>
                        d.udNotHiredHours / d.udStandardWorkHours);

                    if (profile.DateQuit.HasValue)
                    {
                        //Cộng thêm số ngày đã nghỉ việc
                        totalLeaveDays += attendanceTable.Att_AttendanceTableItem.Sum(d =>
                            d.udTerminatedHours / d.udStandardWorkHours);
                    }

                    //Tính số ngày công tính lương = số ngày công chuẩn - tổng số ngày nghỉ
                    attendanceTable.PaidWorkDayCount = attendanceTable.StdWorkDayCount - totalLeaveDays;

                    if (attendanceTable.PaidWorkDayCount < 0)
                    {
                        attendanceTable.PaidWorkDayCount = 0;
                    }
                }
                else if ((gradeCfg.IsApplySubSalaryNewQuitEmp.GetBoolean() && workAndPaidLeaveDays >= gradeCfg.MinWorkDayNewQuitEmp.GetDouble()) &&
                    ((profile.DateHire.HasValue && profile.DateHire.Value.Date >= attendanceFrom) || (profile.DateQuit.HasValue && profile.DateQuit.Value.Date <= attendanceTo)))
                {
                    Double totalLeaveDays = attendanceTable.Att_AttendanceTableItem.Sum(it => (it.LeaveHours + it.ExtraLeaveHours) / it.udStandardWorkHours);
                    Double DayNonShiftInUnEmployeeTime = 0;//Thời gian của nhân viên không có lịch làm việc trước khi vào công ty hoặc là sau khi ra khỏi công ty trong tháng

                    if (profile.DateHire.HasValue && profile.DateHire.Value > attendanceFrom)
                    {
                        unHiredDays = profile.DateHire.Value.Subtract(attendanceFrom).Days;

                        for (DateTime DateCheck = attendanceFrom; DateCheck < profile.DateHire.Value; DateCheck = DateCheck.AddDays(1))
                        {
                            if (listMonthShiftID == null || !listMonthShiftID.Any(d =>
                               d.Key.Date == DateCheck.Date && d.Value != null))
                            {
                                DayNonShiftInUnEmployeeTime++;
                            }
                        }
                    }

                    if (profile.DateQuit.HasValue && profile.DateQuit.Value < attendanceTo)
                    {
                        terminatedDays = attendanceTo.Subtract(profile.DateQuit.Value).Days + 1;
                        for (DateTime DateCheck = profile.DateQuit.Value; DateCheck < attendanceTo; DateCheck = DateCheck.AddDays(1))
                        {
                            if (listMonthShiftID == null || !listMonthShiftID.Any(d =>
                                d.Key.Date == DateCheck.Date && d.Value != null))
                            {
                                DayNonShiftInUnEmployeeTime++;
                            }
                        }
                    }

                    Double paidWorkDay = attendanceTable.StdWorkDayCount - totalLeaveDays;
                    paidWorkDay = paidWorkDay - (unHiredDays + terminatedDays - DayNonShiftInUnEmployeeTime) * gradeCfg.RateUneven.GetDouble();
                    attendanceTable.PaidWorkDayCount = paidWorkDay;
                }
            }

            #region Tính tổng thời gian theo từng loại ngày nghỉ và loại làm thêm

            TotalGroupByLeaveDayType(attendanceTable, attendanceTo);
            TotalGroupByOvertimeType(attendanceTable, attendanceTo);

            #endregion

            #region Tính tổng thời gian và làm tròn

            attendanceTable.TotalPaidWorkDayCount = attendanceTable.PaidWorkDayCount;
            attendanceTable.TotalRealWorkDayCount = attendanceTable.RealWorkDayCount;

            //Cấu hình làm tròng trễ sớm theo tháng
            if (gradeCfg != null && gradeCfg.IsLateEarlyFirstLastShiftRound == true)
            {
                attendanceTable.LateEarlyDeductionHours = Att_AttendanceLib.RoundLateEarlyMinutes(listLateEarlyRule.Where(d =>
                    d.GradeCfgID == gradeCfg.ID).ToList(), Convert.ToInt32(attendanceTable.LateEarlyDeductionHours * 60)) / 60;
            }

            #endregion

            #endregion

            return attendanceTable != null ? 1 : 0;
        }
Esempio n. 12
0
        private Att_Workday CreateWorkday(IUnitOfWork unitOfWork, DateTime date, Hre_ProfileEntity profile, WorkdayConfig inOutConfig,
            List<Cat_DayOffEntity> listHoliday, List<Att_Workday> listWorkday, Att_Workday workday, bool isFromShift2, Guid? shiftID,
            Cat_Shift shiftInfo, List<Cat_Shift> listShift, Dictionary<DateTime, List<Guid?>> listMonthShifts, out Guid? actualShiftID,
            List<Att_TAMScanLogEntity> listTamScanLogByCardCode, List<Att_TAMScanLogEntity> listTamScanLogByCardCodeUnchecked)
        {
            #region Trường hợp có lịch làm việc

            #region Kiểm tra dữ liệu quẹt theo theo ngày (ca)

            var listTamScanLogByShift = GetTamScanLogByShift(date, listShift, shiftID,
              listMonthShifts, listTamScanLogByCardCodeUnchecked.ToArray());

            //Checked = true để không tự detect shift cho nó
            listTamScanLogByShift.ForEach(d => d.Checked = true);
            actualShiftID = null;

            if (workday == null)
            {
                workday = new Att_Workday();
                unitOfWork.AddObject(typeof(Att_Workday), workday);
            }

            #endregion

            if (inOutConfig == null || inOutConfig.TypeLoadData.IsNullOrEmpty()
                || inOutConfig.TypeLoadData == TypeLoadData.E_DEFAULT.ToString()
                || inOutConfig.TypeLoadData == TypeLoadData.E_MAXMIN.ToString())
            {
                if (listTamScanLogByShift.Count() >= 2)
                {
                    #region Trường hợp có ít nhất 2 dòng quẹt thẻ thuộc ca đang xét

                    var inTime = listTamScanLogByShift.Select(d => d.TimeLog).FirstOrDefault();
                    var outTime = listTamScanLogByShift.Select(d => d.TimeLog).LastOrDefault();

                    //Khi phát hiện 2 quẹt thẻ hợp lệ với ca đăng ký thì nhân luôn - không detect shift
                    workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > inTime ? inTime : workday.FirstInTime;
                    workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < outTime ? outTime : workday.LastOutTime;

                    if (isFromShift2)
                    {
                        workday.InTime2 = inTime;
                        workday.OutTime2 = outTime;
                    }
                    else
                    {
                        workday.InTime1 = inTime;
                        workday.OutTime1 = outTime;
                    }

                    if (inOutConfig.DetectWrongShift == Boolean.TrueString)
                    {
                        //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID
                        actualShiftID = GetDetectedShiftID(inTime, outTime, listShift, null);

                        if (actualShiftID != Guid.Empty && actualShiftID != shiftID)
                        {
                            var listTest = GetTamScanLogByShift(inTime.Value.Date, listShift,
                                actualShiftID, listMonthShifts, listTamScanLogByShift.ToArray());

                            if (listTest != null && listTest.Count() >= 2 && listTest.Any(d =>
                                d.TimeLog.HasValue && d.TimeLog.Value.Date == date))
                            {
                                workday.Type = WorkdayType.E_WRONG_SHIFT.ToString();
                            }
                            else
                            {
                                actualShiftID = null;
                            }
                        }
                    }

                    #endregion
                }
                else if (listTamScanLogByShift.Count() == 1)
                {
                    #region Trường hợp có 1 dòng quẹt thẻ thuộc ca đang xét

                    if (listTamScanLogByShift.Any(d => d.SrcType == TAMScanType.E_OUT.ToString()))
                    {
                        //Dữ liệu quẹt thẻ được lấy từ máy chấm công ra - có option máy vào máy ra
                        workday.Type = WorkdayType.E_MISS_IN.ToString();

                        if (isFromShift2)
                        {
                            workday.OutTime2 = listTamScanLogByShift.Select(d => d.TimeLog).LastOrDefault();
                        }
                        else
                        {
                            workday.OutTime1 = listTamScanLogByShift.Select(d => d.TimeLog).LastOrDefault();
                        }
                    }
                    else
                    {
                        //So sanh độ lệch với thời gian của ca -> gần bên nào thì tính theo bên đó
                        var timeLog = listTamScanLogByShift.Select(d => d.TimeLog).FirstOrDefault();
                        var shiftInTime = date.Add(shiftInfo.InTime.TimeOfDay);

                        if (timeLog.Value <= shiftInTime || timeLog.Value.Subtract(shiftInTime)
                            < shiftInTime.AddHours(shiftInfo.CoOut).Subtract(timeLog.Value))
                        {
                            //1 dòng quẹt thẻ rơi vào nửa đầu của ca
                            workday.Type = WorkdayType.E_MISS_OUT.ToString();

                            if (isFromShift2)
                            {
                                workday.InTime2 = timeLog;
                            }
                            else
                            {
                                workday.InTime1 = timeLog;
                            }
                        }

                        if (inOutConfig.DetectWrongShift == Boolean.TrueString)
                        {
                            #region Tìm quẹt thẻ phía trước

                            //Quẹt thẻ gần với thời gian vào của ca -> miss-out hoặc làm sai ca
                            //Tìm ca làm việc trước gần nhất và dòng quẹt thẻ trước gần nhất của nhân viên đang xét
                            var preShift = listMonthShifts.Where(d => d.Key >= date.AddDays(-1) && d.Key < date).OrderByDescending(d => d.Key).FirstOrDefault();
                            var preShiftValue = preShift.Value != null && preShift.Value.Count() > 0 ? preShift.Value.LastOrDefault() : null;

                            //Lấy dòng quẹt thẻ hiện tại và 2 dòng quẹt thẻ phía trước gần nhất của nhân viên đang xét để kiểm tra ca trước
                            var listPreTamScanLog = listTamScanLogByCardCode.Where(d => d.TimeLog <= timeLog).OrderByDescending(d => d.TimeLog).Take(3).ToList();
                            var listTamScanLogByPreShift = GetTamScanLogByShift(preShift.Key, listShift, preShiftValue, listMonthShifts, listPreTamScanLog.ToArray());

                            //Nếu 2 dòng quẹt thẻ phía trước không thuộc một ca khác trong lịch của nhân viên
                            if (listTamScanLogByPreShift == null || listTamScanLogByPreShift.Count() < 2)
                            {
                                var preTamScanLog = listPreTamScanLog.Where(d => d.TimeLog < timeLog).FirstOrDefault();
                                var currentShiftDuration = shiftInfo.MinIn + shiftInfo.CoOut + shiftInfo.MaxOut;

                                if (preTamScanLog != null && listWorkday.Any(d => d.ProfileID == profile.ID && (d.InTime1 == preTamScanLog.TimeLog
                                    || d.InTime2 == preTamScanLog.TimeLog || d.InTime3 == preTamScanLog.TimeLog || d.InTime4 == preTamScanLog.TimeLog
                                    || d.OutTime1 == preTamScanLog.TimeLog || d.OutTime2 == preTamScanLog.TimeLog || d.OutTime3 == preTamScanLog.TimeLog
                                    || d.OutTime4 == preTamScanLog.TimeLog)))
                                {
                                    //Trường hợp quẹt thẻ này đã sử dụng
                                    preTamScanLog = null;
                                }

                                //Nếu quẹt thẻ hiện tại kết với quẹt thẻ tiếp theo mà phù hợp duration thì ghép sai ca
                                if (preTamScanLog != null && preTamScanLog.TimeLog.HasValue && timeLog.Value
                                    .Subtract(preTamScanLog.TimeLog.Value).TotalHours <= currentShiftDuration)
                                {
                                    //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID
                                    actualShiftID = GetDetectedShiftID(preTamScanLog.TimeLog, timeLog, listShift, null);

                                    var listTest = GetTamScanLogByShift(preTamScanLog.TimeLog.Value.Date, listShift, actualShiftID,
                                        listMonthShifts, new Att_TAMScanLogEntity[] { preTamScanLog, listTamScanLogByShift.FirstOrDefault() });

                                    if (preTamScanLog.TimeLog.Value.Date == date.Date && listTest != null && listTest.Count() >= 2
                                        && !listTest.Any(d => d.TimeLog.HasValue && d.TimeLog.Value.Date < date.Date))
                                    {
                                        if (isFromShift2)
                                        {
                                            workday.InTime2 = preTamScanLog.TimeLog;
                                            workday.OutTime2 = timeLog;
                                        }
                                        else
                                        {
                                            workday.InTime1 = preTamScanLog.TimeLog;
                                            workday.OutTime1 = timeLog;
                                        }

                                        workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > preTamScanLog.TimeLog ? preTamScanLog.TimeLog : workday.FirstInTime;
                                        workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < timeLog ? timeLog : workday.LastOutTime;

                                        workday.Type = WorkdayType.E_WRONG_SHIFT.ToString();
                                        preTamScanLog.Checked = true;
                                    }
                                    else
                                    {
                                        actualShiftID = null;
                                    }
                                }
                            }

                            #endregion

                            #region Tìm quẹt thẻ phía sau

                            if (workday.Type == WorkdayType.E_MISS_OUT.ToString()
                                || string.IsNullOrWhiteSpace(workday.Type))
                            {
                                if (string.IsNullOrWhiteSpace(workday.Type))
                                {
                                    //1 dòng quẹt thẻ rơi vào nửa sau của ca
                                    workday.Type = WorkdayType.E_MISS_IN.ToString();

                                    if (isFromShift2)
                                    {
                                        workday.OutTime2 = timeLog;
                                    }
                                    else
                                    {
                                        workday.OutTime1 = timeLog;
                                    }
                                }

                                //Quẹt thẻ gần với thời gian ra của ca -> miss-in hoặc làm sai ca
                                //Tìm ca làm việc tiếp theo gần nhất và dòng quẹt thẻ tiếp theo gần nhất của nhân viên đang xét
                                var nextShift = listMonthShifts.Where(d => d.Key > date && d.Key <= date.AddDays(1)).OrderBy(d => d.Key).FirstOrDefault();
                                var nextShiftValue = nextShift.Value != null && nextShift.Value.Count() > 0 ? nextShift.Value.FirstOrDefault() : null;

                                //Lấy dòng quẹt thẻ hiện tại và 2 dòng quẹt thẻ tiếp theo gần nhất của nhân viên đang xét để kiểm tra ca tiếp theo
                                var listNextTamScanLog = listTamScanLogByCardCodeUnchecked.Where(d => d.TimeLog >= timeLog).OrderBy(d => d.TimeLog).Take(3).ToList();
                                var listTamScanLogByNextShift = GetTamScanLogByShift(nextShift.Key, listShift, nextShiftValue, listMonthShifts, listNextTamScanLog.ToArray());

                                //Nếu 2 dòng quẹt thẻ tiếp theo không thuộc một ca khác trong lịch của nhân viên
                                if (listTamScanLogByNextShift == null || listTamScanLogByNextShift.Count() < 2)
                                {
                                    var nextTamScanLog = listNextTamScanLog.Where(d => d.TimeLog > timeLog).FirstOrDefault();
                                    var currentShiftDuration = shiftInfo.MinIn + shiftInfo.CoOut + shiftInfo.MaxOut;

                                    //Nếu quẹt thẻ hiện tại kết với quẹt thẻ tiếp theo mà phù hợp duration thì ghép sai ca
                                    if (nextTamScanLog != null && nextTamScanLog.TimeLog.HasValue && nextTamScanLog
                                        .TimeLog.Value.Subtract(timeLog.Value).TotalHours <= currentShiftDuration)
                                    {
                                        //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID
                                        actualShiftID = GetDetectedShiftID(timeLog, nextTamScanLog.TimeLog, listShift, null);

                                        var listTest = GetTamScanLogByShift(timeLog.Value.Date, listShift, actualShiftID, listMonthShifts,
                                            new Att_TAMScanLogEntity[] { listTamScanLogByShift.FirstOrDefault(), nextTamScanLog });

                                        if (timeLog.Value.Date == date.Date && listTest != null && listTest.Count() >= 2
                                            && !listTest.Any(d => d.TimeLog.HasValue && d.TimeLog.Value.Date < date.Date))
                                        {
                                            if (isFromShift2)
                                            {
                                                workday.InTime1 = timeLog;
                                                workday.OutTime1 = nextTamScanLog.TimeLog;
                                            }
                                            else
                                            {
                                                workday.InTime1 = timeLog;
                                                workday.OutTime1 = nextTamScanLog.TimeLog;
                                            }

                                            workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > timeLog ? timeLog : workday.FirstInTime;
                                            workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < nextTamScanLog.TimeLog ? nextTamScanLog.TimeLog : workday.LastOutTime;

                                            workday.Type = WorkdayType.E_WRONG_SHIFT.ToString();
                                            nextTamScanLog.Checked = true;
                                        }
                                        else
                                        {
                                            actualShiftID = null;
                                        }
                                    }
                                }
                            }

                            #endregion
                        }
                        else
                        {
                            if (IsInTime(date, timeLog, shiftInfo))
                            {
                                if (isFromShift2)
                                {
                                    workday.InTime2 = timeLog;
                                }
                                else
                                {
                                    workday.InTime1 = timeLog;
                                }

                                workday.Type = WorkdayType.E_MISS_OUT.ToString();
                            }
                            else
                            {
                                if (isFromShift2)
                                {
                                    workday.OutTime2 = timeLog;
                                }
                                else
                                {
                                    workday.OutTime1 = timeLog;
                                }

                                workday.Type = WorkdayType.E_MISS_IN.ToString();
                            }
                        }
                    }

                    #endregion
                }
                else
                {
                    #region Trường hợp không có dòng quẹt thẻ thuộc ca đang xét

                    var listTamScanLogByDate = listTamScanLogByCardCodeUnchecked.Where(d =>
                        d.TimeLog.Value.Date == date).ToList();

                    var shiftInTime = date.Add(shiftInfo.InTime.TimeOfDay);
                    var listTimeLog = new List<Att_TAMScanLogEntity>();
                    bool isWrongShiftDetected = false;

                    foreach (var item in listTamScanLogByDate)
                    {
                        if (item.TimeLog < shiftInTime)
                        {
                            //Quẹt thẻ gần với thời gian vào của ca -> miss-out hoặc làm sai ca
                            //Tìm ca làm việc trước gần nhất và dòng quẹt thẻ trước gần nhất của nhân viên đang xét
                            var preShift = listMonthShifts.Where(d => d.Key >= date.AddDays(-1) && d.Key < date).OrderByDescending(d => d.Key).FirstOrDefault();
                            var preShiftValue = preShift.Value != null && preShift.Value.Count() > 0 ? preShift.Value.LastOrDefault() : null;

                            //Lấy dòng quẹt thẻ hiện tại và 2 dòng quẹt thẻ phía trước gần nhất của nhân viên đang xét để kiểm tra ca trước
                            var listPreTamScanLog = listTamScanLogByCardCode.Where(d => d.TimeLog <= item.TimeLog).OrderByDescending(d => d.TimeLog).Take(3).ToList();
                            var listTamScanLogByPreShift = GetTamScanLogByShift(preShift.Key, listShift, preShiftValue, listMonthShifts, listPreTamScanLog.ToArray());

                            //Nếu 2 dòng quẹt thẻ phía trước không thuộc một ca khác trong lịch của nhân viên
                            if (listTamScanLogByPreShift == null || listTamScanLogByPreShift.Count() < 2)
                            {
                                var preTamScanLog = listPreTamScanLog.Where(d => d.TimeLog < item.TimeLog).FirstOrDefault();
                                var currentShiftDuration = shiftInfo.MinIn + shiftInfo.CoOut + shiftInfo.MaxOut;

                                if (preTamScanLog != null && listWorkday.Any(d => d.ProfileID == profile.ID && (d.InTime1 == preTamScanLog.TimeLog
                                    || d.InTime2 == preTamScanLog.TimeLog || d.InTime3 == preTamScanLog.TimeLog || d.InTime4 == preTamScanLog.TimeLog
                                    || d.OutTime1 == preTamScanLog.TimeLog || d.OutTime2 == preTamScanLog.TimeLog || d.OutTime3 == preTamScanLog.TimeLog
                                    || d.OutTime4 == preTamScanLog.TimeLog)))
                                {
                                    //Trường hợp quẹt thẻ này đã sử dụng
                                    preTamScanLog = null;
                                }

                                //Nếu quẹt thẻ hiện tại kết với quẹt thẻ trước đó mà phù hợp duration thì ghép sai ca
                                if (preTamScanLog != null && preTamScanLog.TimeLog.HasValue && item.TimeLog.Value
                                    .Subtract(preTamScanLog.TimeLog.Value).TotalHours <= currentShiftDuration)
                                {
                                    //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID
                                    actualShiftID = GetDetectedShiftID(preTamScanLog.TimeLog, item.TimeLog, listShift, null);

                                    var listTest = GetTamScanLogByShift(preTamScanLog.TimeLog.Value.Date, listShift, actualShiftID,
                                        listMonthShifts, new Att_TAMScanLogEntity[] { preTamScanLog, item });

                                    if (preTamScanLog.TimeLog.Value.Date == date.Date && listTest != null && listTest.Count() >= 2
                                        && listTest.Any(d => d.TimeLog.HasValue && d.TimeLog.Value.Date < date.Date))
                                    {
                                        if (isFromShift2)
                                        {
                                            workday.InTime2 = preTamScanLog.TimeLog;
                                            workday.OutTime2 = item.TimeLog;
                                        }
                                        else
                                        {
                                            workday.InTime1 = preTamScanLog.TimeLog;
                                            workday.OutTime1 = item.TimeLog;
                                        }

                                        workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > preTamScanLog.TimeLog ? preTamScanLog.TimeLog : workday.FirstInTime;
                                        workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < item.TimeLog ? item.TimeLog : workday.LastOutTime;

                                        workday.Type = WorkdayType.E_WRONG_SHIFT.ToString();
                                        preTamScanLog.Checked = true;
                                        isWrongShiftDetected = true;
                                        break;//chỉ hỗ trợ 1 ca
                                    }
                                    else
                                    {
                                        actualShiftID = null;
                                    }
                                }
                                else
                                {
                                    listTimeLog.Add(item);
                                }
                            }
                            else
                            {
                                if (!listTamScanLogByPreShift.Any(d => d.TimeLog == item.TimeLog))
                                {
                                    listTimeLog.Add(item);
                                }

                                listTimeLog = listTimeLog.Where(d => !listTamScanLogByPreShift.Contains(d)).ToList();
                            }
                        }
                        else if (item.TimeLog > shiftInTime)
                        {
                            //Quẹt thẻ gần với thời gian ra của ca -> miss-in hoặc làm sai ca
                            //Tìm ca làm việc tiếp theo gần nhất và dòng quẹt thẻ tiếp theo gần nhất của nhân viên đang xét
                            var nextShift = listMonthShifts.Where(d => d.Key > date && d.Key <= date.AddDays(1)).OrderBy(d => d.Key).FirstOrDefault();
                            var nextShiftValue = nextShift.Value != null && nextShift.Value.Count() > 0 ? nextShift.Value.FirstOrDefault() : null;

                            //Lấy dòng quẹt thẻ hiện tại và 2 dòng quẹt thẻ tiếp theo gần nhất của nhân viên đang xét để kiểm tra ca tiếp theo
                            var listNextTamScanLog = listTamScanLogByCardCodeUnchecked.Where(d => d.TimeLog >= item.TimeLog).OrderBy(d => d.TimeLog).Take(3).ToList();
                            var listTamScanLogByNextShift = GetTamScanLogByShift(nextShift.Key, listShift, nextShiftValue, listMonthShifts, listNextTamScanLog.ToArray());

                            //Nếu 2 dòng quẹt thẻ tiếp theo không thuộc một ca khác trong lịch của nhân viên
                            if (listTamScanLogByNextShift == null || listTamScanLogByNextShift.Count() < 2)
                            {
                                var nextTamScanLog = listNextTamScanLog.Where(d => d.TimeLog > item.TimeLog).FirstOrDefault();
                                var currentShiftDuration = shiftInfo.MinIn + shiftInfo.CoOut + shiftInfo.MaxOut;

                                //Nếu quẹt thẻ hiện tại kết với quẹt thẻ tiếp theo mà phù hợp duration thì ghép sai ca
                                if (nextTamScanLog != null && nextTamScanLog.TimeLog.HasValue && nextTamScanLog
                                    .TimeLog.Value.Subtract(item.TimeLog.Value).TotalHours <= currentShiftDuration)
                                {
                                    //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID
                                    actualShiftID = GetDetectedShiftID(item.TimeLog, nextTamScanLog.TimeLog, listShift, null);

                                    var listTest = GetTamScanLogByShift(item.TimeLog.Value.Date, listShift, actualShiftID,
                                        listMonthShifts, new Att_TAMScanLogEntity[] { item, nextTamScanLog });

                                    if (item.TimeLog.Value.Date == date.Date && listTest != null && listTest.Count() >= 2
                                        && listTest.Any(d => d.TimeLog.HasValue && d.TimeLog.Value.Date < date.Date))
                                    {
                                        if (isFromShift2)
                                        {
                                            workday.InTime2 = item.TimeLog;
                                            workday.OutTime2 = nextTamScanLog.TimeLog;
                                        }
                                        else
                                        {
                                            workday.InTime1 = item.TimeLog;
                                            workday.OutTime1 = nextTamScanLog.TimeLog;
                                        }

                                        workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > item.TimeLog ? item.TimeLog : workday.FirstInTime;
                                        workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < nextTamScanLog.TimeLog ? nextTamScanLog.TimeLog : workday.LastOutTime;

                                        workday.Type = WorkdayType.E_WRONG_SHIFT.ToString();
                                        nextTamScanLog.Checked = true;
                                        isWrongShiftDetected = true;
                                        break;//chỉ hỗ trợ 1 ca
                                    }
                                    else
                                    {
                                        actualShiftID = null;
                                    }
                                }
                                else
                                {
                                    listTimeLog.Add(item);
                                }
                            }
                            else
                            {
                                if (!listTamScanLogByNextShift.Any(d => d.TimeLog == item.TimeLog))
                                {
                                    listTimeLog.Add(item);
                                }

                                listTimeLog = listTimeLog.Where(d => !listTamScanLogByNextShift.Contains(d)).ToList();
                            }
                        }
                    }

                    if (!isWrongShiftDetected)
                    {
                        var listRemove = new List<Att_TAMScanLogEntity>();

                        if (listTimeLog.Count() >= 2)
                        {
                            var currentShiftDuration = shiftInfo.MinIn + shiftInfo.CoOut + shiftInfo.MaxOut;
                            var timeLog1 = listTimeLog.OrderBy(d => d.TimeLog).FirstOrDefault();
                            var timeLog2 = listTimeLog.OrderBy(d => d.TimeLog).LastOrDefault();

                            if (isFromShift2)
                            {
                                workday.InTime2 = timeLog1.TimeLog;
                                workday.OutTime2 = timeLog2.TimeLog;
                            }
                            else
                            {
                                workday.InTime1 = timeLog1.TimeLog;
                                workday.OutTime1 = timeLog2.TimeLog;
                            }

                            workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > timeLog1.TimeLog ? timeLog1.TimeLog : workday.FirstInTime;
                            workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < timeLog2.TimeLog ? timeLog2.TimeLog : workday.LastOutTime;
                            isWrongShiftDetected = true;

                            if (timeLog2.TimeLog.HasValue && timeLog1.TimeLog.HasValue && timeLog2.TimeLog.Value
                                .Subtract(timeLog1.TimeLog.Value).TotalHours <= currentShiftDuration)
                            {
                                //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID
                                actualShiftID = GetDetectedShiftID(timeLog1.TimeLog, timeLog2.TimeLog, listShift, null);

                                var listTest = GetTamScanLogByShift(timeLog1.TimeLog.Value.Date, listShift, actualShiftID,
                                    listMonthShifts, new Att_TAMScanLogEntity[] { timeLog1, timeLog2 });

                                if (listTest != null && listTest.Count() >= 2 && listTest.Any(d =>
                                    d.TimeLog.HasValue && d.TimeLog.Value.Date < date.Date))
                                {
                                    workday.Type = WorkdayType.E_WRONG_SHIFT.ToString();
                                }
                                else
                                {
                                    workday.Type = WorkdayType.E_LONGIN_SHIFT.ToString();
                                }
                            }
                            else
                            {
                                foreach (var item in listTimeLog.Where(d => d.TimeLog > timeLog1.TimeLog).OrderByDescending(d => d.TimeLog))
                                {
                                    if (isFromShift2)
                                    {
                                        workday.OutTime2 = item.TimeLog;
                                    }
                                    else
                                    {
                                        workday.OutTime1 = item.TimeLog;
                                    }

                                    workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < item.TimeLog ? item.TimeLog : workday.LastOutTime;

                                    if (item.TimeLog > timeLog1.TimeLog && item.TimeLog.HasValue && timeLog1.TimeLog.HasValue
                                        && item.TimeLog.Value.Subtract(timeLog1.TimeLog.Value).TotalHours <= currentShiftDuration)
                                    {
                                        workday.Type = WorkdayType.E_DETECTED_SHIFT.ToString();
                                        break;
                                    }
                                    else
                                    {
                                        workday.Type = WorkdayType.E_LONGIN_SHIFT.ToString();
                                    }
                                }

                                listRemove = listTimeLog.Where(d => d.TimeLog > workday.LastOutTime).ToList();
                            }
                        }
                        else if (listTimeLog.Count() == 1)
                        {
                            if (listTimeLog.Any(d => d.TimeLog < shiftInTime))
                            {
                                var inTimeValue = listTimeLog.Select(d => d.TimeLog).FirstOrDefault();

                                if (isFromShift2)
                                {
                                    workday.InTime2 = inTimeValue;
                                }
                                else
                                {
                                    workday.InTime1 = inTimeValue;
                                }

                                workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > inTimeValue ? inTimeValue : workday.FirstInTime;
                                workday.Type = WorkdayType.E_MISS_OUT.ToString();//miss-in hay miss-out cũng như nhau
                            }
                            else
                            {
                                var outTimeValue = listTimeLog.Select(d => d.TimeLog).FirstOrDefault();

                                if (isFromShift2)
                                {
                                    workday.OutTime2 = outTimeValue;
                                }
                                else
                                {
                                    workday.OutTime1 = outTimeValue;
                                }

                                workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < outTimeValue ? outTimeValue : workday.LastOutTime;
                                workday.Type = WorkdayType.E_MISS_IN.ToString();//miss-in hay miss-out cũng như nhau
                            }

                            isWrongShiftDetected = true;
                        }

                        listTimeLog.Where(d => !listRemove.Contains(d)).ToList().ForEach(d => d.Checked = true);
                    }

                    if (!isWrongShiftDetected)
                    {
                        if (listHoliday.Any(d => d.DateOff.Date == date.Date))
                        {
                            //Có ca mà không inout thì xem có phải holiday
                            workday.Type = WorkdayType.E_HOLIDAY.ToString();
                        }
                        else
                        {
                            workday.Type = WorkdayType.E_MISS_IN_OUT.ToString();
                        }
                    }

                    #endregion
                }
            }
            else if (inOutConfig.TypeLoadData == TypeLoadData.E_TYPEINOUT.ToString())
            {
                //Xử lý cho các loại khác
            }
            return workday;
            #endregion
        }
Esempio n. 13
0
        /// <summary> set giá trị BC D02 </summary>
        /// <param name="profile"></param>
        /// <param name="status"></param>
        /// <param name="firstSal"></param>
        /// <param name="currentSal"></param>
        /// <param name="MonthYear"></param>
        /// <param name="orgStructures"></param>
        /// <param name="status1"></param>
        /// <param name="orderGroup">Số Thứ tự theo tăng , giảm (I,II,I.1)</param>
        /// <returns></returns>
        private Ins_InsuranceReportD02Entity SetReportD02(Hre_ProfileEntity profile, string status, double firstSal, double currentSal, DateTime MonthYear, List<Cat_OrgStructureEntity> orgStructures, string status1, string orderGroup)
        {
            var ins_d02 = new Ins_InsuranceReportD02Entity()
            {
                CodeEmp = profile.CodeEmp,
                Comment = GetDescription(status),
                ProfileName = profile.ProfileName,
                SocialInsNo = profile.SocialInsNo,
                OrderGroup = orderGroup,
                Status1 = status1,
                Status = status,
                JobTitle = profile.JobTitleName,
                Position = profile.PositionName,
                ProfileID = profile.ID,
                Gender = profile.Gender,
                DateOfBirth = profile.DateOfBirth.HasValue ? profile.DateOfBirth.Value.ToString(ConstantFormat.HRM_Format_DayMonthYear) : string.Empty,
                HireDate = profile.DateHire ?? DateTime.Now,
                EndProbationDate = profile.DateEndProbation ?? DateTime.Now,
                EndDate = profile.DateEnd ?? DateTime.Now,
                RateBHXH = RateSocial,
                RateBHYT = RateHealth,
                RateBHTN = RateUnEmp,
                WorkPlaceID = profile.WorkPlaceID,
                SocialInsPlaceID = profile.SocialInsPlaceID,
                Allowance1 = profile.Allowance1,
                Allowance2 = profile.Allowance2,
                Allowance3 = profile.Allowance3,
                Allowance4 = profile.Allowance4,
                AllowanceAdditional = profile.AllowanceAdditional,
                JobName = profile.JobName
            };

            if (string.IsNullOrEmpty(ins_d02.Position))
            {
                ins_d02.Position = ins_d02.JobTitle;
            }

            if (profile.OrgStructureID.HasValue)
            {
                ins_d02.CodeParentOrgLevel = GetCodeOrgStructure(orgStructures, profile.OrgStructureID ?? Guid.Empty);
            }

            if (status == TypeInsuranceD02TS.E_TANG_LUONG.ToString())
            {
                ins_d02.OldBasicSalary = firstSal;
                ins_d02.NewBasicSalary = currentSal;
            }
            else if (status == TypeInsuranceD02TS.E_TANG_LUONG_CHANGEJOBNAME.ToString())
            {
                ins_d02.OldBasicSalary = firstSal;
                ins_d02.NewBasicSalary = currentSal;
            }
            else if (status == TypeInsuranceD02TS.E_GIAM_LUONG.ToString()) //Ho tro masan xuat trang thai tru co luong ngay 12/08/2013
            {
                ins_d02.OldBasicSalary = firstSal;
                ins_d02.NewBasicSalary = currentSal;
            }
            else if (status == TypeInsuranceD02TS.E_GIAM_LUONG_CHANGEJOBNAME.ToString())
            {
                ins_d02.OldBasicSalary = firstSal;
                ins_d02.NewBasicSalary = currentSal;
            }
            else if (status == TypeInsuranceD02TS.E_GIAM_LEAVE_14WORKINGDAYS.ToString())
            {
                ins_d02.OldBasicSalary = firstSal;
                ins_d02.NewBasicSalary = firstSal;
            }
            else if (status == TypeInsuranceD02TS.E_TANG_LD.ToString() || status == TypeInsuranceD02TS.E_TANG_BENH.ToString() || status == TypeInsuranceD02TS.E_TANG_TS.ToString() || status == TypeInsuranceD02TS.E_TANG_LEAVE_14WORKINGDAYS.ToString())
            {
                ins_d02.OldBasicSalary = 0;
                ins_d02.NewBasicSalary = currentSal;
            }

            else if (status == TypeInsuranceD02TS.E_GIAM_BHYT.ToString() || status == TypeInsuranceD02TS.E_TANG_BHYT.ToString())
            {
                ins_d02.OldBasicSalary = firstSal;
                ins_d02.NewBasicSalary = currentSal;
                ins_d02.RateBHXH = 0;
                ins_d02.RateBHYT = RateHealth;
                ins_d02.RateBHTN = 0;
            }
            else if (status == TypeInsuranceD02TS.E_GIAM_BHTN.ToString() || status == TypeInsuranceD02TS.E_TANG_BHTN.ToString())
            {
                ins_d02.OldBasicSalary = firstSal;
                ins_d02.NewBasicSalary = currentSal;
                ins_d02.RateBHXH = 0;
                ins_d02.RateBHYT = 0;
                ins_d02.RateBHTN = RateUnEmp;
            }
            else if (status == TypeInsuranceD02TS.E_GIAM_LD.ToString() || status == TypeInsuranceD02TS.E_GIAM_LD_BHYT.ToString())
            {
                ins_d02.OldBasicSalary = firstSal;
                ins_d02.NewBasicSalary = firstSal;
            }
            else if (status == TypeInsuranceD02TS.E_GIAM_TS.ToString() || status == TypeInsuranceD02TS.E_GIAM_TS_QUIT.ToString())
            {
                ins_d02.OldBasicSalary = firstSal;
                ins_d02.NewBasicSalary = firstSal;
            }
            else if (status == TypeInsuranceD02TS.E_GIAM_LD_NOT_BHYT.ToString() || status == TypeInsuranceD02TS.E_GIAM_LD_BHYT.ToString()
                || status == TypeInsuranceD02TS.E_GIAM_LD_BHYT_KOKIPTHOI.ToString() || status == TypeInsuranceD02TS.E_GIAM_QUIT_SUSPENSE.ToString()) //Ho tro masan xuat trang thai tru co luong ngay 12/08/2013
            {
                ins_d02.OldBasicSalary = firstSal;
                ins_d02.NewBasicSalary = firstSal;
            }
            else if (status == TypeInsuranceD02TS.E_CHANGEJOBNAME.ToString())
            {
                ins_d02.OldBasicSalary = firstSal;
                ins_d02.NewBasicSalary = currentSal;
            }
            else if (status == TypeInsuranceD02TS.E_GIAM_LD.ToString() || status == TypeInsuranceD02TS.E_GIAM_LD_BHYT.ToString()
                || status == TypeInsuranceD02TS.E_GIAM_LD_BHYT_KOKIPTHOI.ToString() || status == TypeInsuranceD02TS.E_GIAM_LD_NOT_BHYT.ToString())
            {
                ins_d02.OldBasicSalary = firstSal;
                ins_d02.NewBasicSalary = firstSal;
            }

            ins_d02.MonthNow = new DateTime(MonthYear.Year, MonthYear.Month, 1);
            ins_d02.TitleMonthNow = "Số:..........Tháng " + MonthYear.Month + " Năm " + MonthYear.Year;
            ins_d02.FromMonth = new DateTime(MonthYear.AddMonths(-1).Year, MonthYear.AddMonths(-1).Month, 1);
            ins_d02.ToMonth = new DateTime(MonthYear.Year, MonthYear.Month, 1);
            ins_d02.Status = status;
            //dr["CodeParentOrgLevel"] = HRService.GetCodeInListOrgParent(pro.OrgStructureID ?? Guid.Empty, lstStrucAll, 1);

            return ins_d02;

        }
Esempio n. 14
0
        List<Cat_DayOff> GetListDayOffPerProfile(List<Att_LeaveDay> lstLeaveDayHoliday, Hre_ProfileEntity profile, List<Cat_DayOff> lstDayOff, string E_HOLIDAY_HLD)
        {
            //string strCat_DayOff = CachObjects.ListCat_DayOff;
            //if (Cache[strCat_DayOff] == null)
            //    SecurityService.CacheBaseCat_Holiday();

            List<Att_LeaveDay> lstLeaveDayHolidayTemp = lstLeaveDayHoliday.Where(att => att.ProfileID == profile.ID).ToList();
            List<Cat_DayOff> lstDayOffPerProfile = new List<Cat_DayOff>();

            // lstDayOffPerProfile = SecurityService.CacheBaseCat_Holiday();

            #region Clone danh sach ngay nghi

            foreach (Cat_DayOff dayoff in lstDayOff)
            {
                lstDayOffPerProfile.Add(new Cat_DayOff()
                {
                    ID = dayoff.ID,
                    DateOff = dayoff.DateOff,
                    Type = dayoff.Type//Ngày nghỉ ngày thành ngày nghỉ Holiday
                });
            }

            #endregion

            if (lstLeaveDayHolidayTemp.Count() > 0)
            {
                foreach (Att_LeaveDay att in lstLeaveDayHolidayTemp)
                {
                    for (DateTime idx = att.DateStart.Date; idx <= att.DateEnd.Date; idx = idx.AddDays(1))
                    {
                        List<Cat_DayOff> lstDayofftemp = lstDayOffPerProfile.Where(da => att.DateStart.Date >= da.DateOff.Date
                            && att.DateEnd.Date <= da.DateOff.Date).ToList();
                        if (lstDayofftemp.Count() == 0)//Danh sách ngày nghỉ mỗi người chưa có ngày này --Trung.Le
                            lstDayOffPerProfile.Add(new Cat_DayOff()
                            {
                                DateOff = idx,
                                Type = E_HOLIDAY_HLD//Ngày nghỉ ngày thành ngày nghỉ Holiday
                            });
                        else//Danh sách ngày nghỉ mỗi người đã có ngày này --Trung.Le
                            lstDayofftemp[0].Type = E_HOLIDAY_HLD;//Chỉnh ngày nghỉ ngày thành ngày nghỉ Holiday
                    }
                }
            }

            return lstDayOffPerProfile;
        }
Esempio n. 15
0
        /// <summary>
        /// Danh Sách Chi Tiết Nhân Viên Hưởng Chế Độ Hiếu Hỉ
        /// </summary>
        /// <param name="datestart"></param>
        /// <param name="dateend"></param>
        /// <returns></returns>
        public DataTable ReportProfileEntitledAllowance(DateTime datestart, DateTime dateend, List<Guid> ListProfileIds, string OrgStructure, string UserLogin, bool isIncludeQuitEmp)
        {
            string status = string.Empty;
            List<object> listModel = new List<object>();

            listModel = new List<object>();
            listModel.AddRange(new object[7]);
            listModel[3] = datestart;
            listModel[4] = dateend;
            listModel[5] = 1;
            listModel[6] = Int32.MaxValue - 1;
            List<Sal_UnusualAllowanceEntity> ListUnusualAllowance = GetData<Sal_UnusualAllowanceEntity>(listModel, ConstantSql.hrm_sal_sp_get_UnusualAllowanceFilialWedding, UserLogin, ref status).Where(m => m.IsExcludePayslip == true).ToList();

            listModel = new List<object>();
            listModel.AddRange(new object[17]);
            listModel[2] = OrgStructure;
            listModel[15] = 1;
            listModel[16] = int.MaxValue - 1;
            List<Hre_ProfileEntity> ListProfile = GetData<Hre_ProfileEntity>(listModel, ConstantSql.hrm_hr_sp_get_ProfileAll, UserLogin, ref status);

            listModel = new List<object>();
            listModel.AddRange(new object[6]);
            listModel[4] = 1;
            listModel[5] = Int32.MaxValue - 1;
            List<Cat_UnusualAllowanceCfgEntity> ListUnusualAllowanceCfg = GetData<Cat_UnusualAllowanceCfgEntity>(listModel, ConstantSql.hrm_cat_sp_get_UnusualAllowanceCfg, UserLogin, ref status);

            //loại trự nv nghỉ việc
            if (!isIncludeQuitEmp)
            {
                ListProfile = ListProfile.Where(m => m.DateQuit == null || m.DateQuit >= dateend).ToList();
                ListUnusualAllowance = ListUnusualAllowance.Where(m => ListProfile.Any(t => t.ID == m.ProfileID)).ToList();
            }

            //lọc theo nhân viên
            if (ListProfileIds != null && ListProfileIds.Count > 0)
            {
                ListUnusualAllowance = ListUnusualAllowance.Where(m => ListProfileIds.Any(t => t == m.ProfileID)).ToList();
            }

            //Create column
            DataTable Table = new DataTable("ReportProfileEntitledAllowance");
            Table.Columns.Add("STT");
            Table.Columns.Add("CodeEmp");
            Table.Columns.Add("ProfileName");
            Table.Columns.Add("Department");
            Table.Columns.Add("PaymentDate", typeof(DateTime));
            Table.Columns.Add("TypeMode");
            Table.Columns.Add("WhoIncurredRegime");
            Table.Columns.Add("Relative");
            Table.Columns.Add("DateBorn", typeof(DateTime));
            Table.Columns.Add("Amount", typeof(double));
            Table.Columns.Add("Noted");

            Hre_ProfileEntity ProfileItem = new Hre_ProfileEntity();
            Cat_UnusualAllowanceCfgEntity ListUnusualAllowanceCfgItem = new Cat_UnusualAllowanceCfgEntity();
            for (int i = 0; i < ListUnusualAllowance.Count; i++)
            {
                ProfileItem = ListProfile.Where(m => m.ID == ListUnusualAllowance[i].ProfileID).FirstOrDefault();
                if (ProfileItem == null)
                {
                    continue;
                }
                DataRow row = Table.NewRow();
                row["STT"] = i + 1;

                if (ProfileItem != null)
                {
                    row["CodeEmp"] = ProfileItem.CodeEmp;
                    row["ProfileName"] = ProfileItem.ProfileName;
                    row["Department"] = ProfileItem.OrgStructureName;
                }
                else
                {
                    row["CodeEmp"] = "";
                    row["ProfileName"] = "";
                    row["Department"] = "";
                }
                ListUnusualAllowanceCfgItem = ListUnusualAllowanceCfg.Where(m => m.ID == ListUnusualAllowance[i].UnusualEDTypeID).FirstOrDefault();
                if (ListUnusualAllowanceCfgItem != null)
                {
                    row["TypeMode"] = ListUnusualAllowanceCfgItem.Code;
                }
                if (ListUnusualAllowance[i].MonthStart != null)
                {
                    row["PaymentDate"] = ListUnusualAllowance[i].MonthStart;
                }

                row["WhoIncurredRegime"] = ListUnusualAllowance[i].RelativeName;
                row["Relative"] = ListUnusualAllowance[i].RelativeTypeName;
                if (ListUnusualAllowance[i].DateOccur != null)
                {
                    row["DateBorn"] = ListUnusualAllowance[i].DateOccur;
                }
                if (ListUnusualAllowance[i].Amount != null)
                {
                    row["Amount"] = ListUnusualAllowance[i].Amount;
                }

                row["Noted"] = ListUnusualAllowance[i].Notes;
                Table.Rows.Add(row);
            }
            return Table;
        }
Esempio n. 16
0
        public List<Hre_CardHistoryEntity> GetCardCodeByProfile(List<Hre_CardHistoryEntity> listCardHistory,
            Hre_ProfileEntity profile, DateTime from, DateTime to)
        {
            List<Hre_CardHistoryEntity> lstCardCode = new List<Hre_CardHistoryEntity>();

            if (profile != null)
            {
                var listCardHistoryByProfile = listCardHistory.Where(his => his.ProfileID == profile.ID
                    && his.DateEffect <= to).OrderByDescending(his => his.DateEffect).ToList();

                //Chay tu ngay hieu luc lon nhat den ngay hieu luc nho nhat           
                foreach (var card in listCardHistoryByProfile)
                {
                    if (card.DateEffect <= from)
                    {
                        lstCardCode.Add(card);
                        break;
                    }
                    else
                    {
                        lstCardCode.Add(card);
                    }
                }
            }

            return lstCardCode;
        }
Esempio n. 17
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="templateID">Template xuất payslip</param>
        /// <param name="lstProfile"></param>
        /// <param name="monthStart"></param>
        /// <param name="monthEnd"></param>
        /// <returns></returns>

        public Boolean CheckSendMail(String emailTo, String outPath, DateTime dateStart, DateTime dateEnd, Hre_ProfileEntity profile)
        {
            using (var context = new VnrHrmDataContext())
            {
                Boolean iSuccess = false;
                var service = new BaseService();
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoSysTemplateSendMail = new CustomBaseRepository<Sys_TemplateSendMail>(unitOfWork);

                string title = dateEnd.ToString("MM-yyyy") + "-" + profile.ProfileName;
                string titleMail = "PaySlip Of " + title;
                string body = string.Empty;

                string typeTemplate = EnumDropDown.EmailType.E_PAYSLIP.ToString();
                var template = repoSysTemplateSendMail.FindBy(s => s.Type == typeTemplate).FirstOrDefault();
                if (template != null)
                {
                    if (!template.Subject.IsNullOrEmpty())
                    {
                        titleMail = template.Subject + title;
                    }
                    string[] strParaFields = new string[] 
                    {
                        Sal_ReportBasicSalaryMonthlyEntity.FieldNames.ProfileName,
                        Sal_ReportBasicSalaryMonthlyEntity.FieldNames.DateFrom,
                        Sal_ReportBasicSalaryMonthlyEntity.FieldNames.DateTo
                    };
                    string[] strParaValues = new string[]
                    {
                        profile.ProfileName,
                        dateStart.ToShortDateString(),
                        dateEnd.ToShortDateString()
                    };
                    body = LibraryService.ReplaceContentFile(template.Content, strParaFields, strParaValues);
                }
                iSuccess = service.SendMail(titleMail, emailTo, body, outPath);
                return iSuccess;
            }
        }
Esempio n. 18
0
        /// <summary>
        /// [Hieu.Van] Tồng hợp dữ liệu ăn
        /// </summary>
        /// <param name="request"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        //[HttpPost]
        public ActionResult GetMealRecordSummary([DataSourceRequest] DataSourceRequest request, Can_MealRecordSummaryModel model)
        {

            Can_MealRecordServices CanService = new Can_MealRecordServices();
            var baseService = new BaseService();
            var Actionservices = new ActionService(UserLogin);
            DateTime dateStart = DateTime.Now;
            DateTime dateEnd = DateTime.Now;
            List<int?> OrgIds = new List<int?>();
            if (model.DateFrom != null)
            {
                dateStart = model.DateFrom.Value;
            }
            if (model.DateTo != null)
            {
                dateEnd = model.DateTo.Value;
            }

            #region xử lý lấy lstProfileIds theo OrgStructureID
            List<Hre_ProfileEntity> lstProfileIDs = new List<Hre_ProfileEntity>();
            string status = string.Empty;
            List<object> lstObj = new List<object>();
            lstObj.Add(model.OrgStructureIDs);
            lstObj.Add(null);
            lstObj.Add(null);
            List<Hre_ProfileEntity> _temp = new List<Hre_ProfileEntity>();
            Hre_ProfileEntity t = new Hre_ProfileEntity();
            List<Hre_ProfileEntity> _profileIDs = new List<Hre_ProfileEntity>();

            if (model.ProfileIDs != null)
            {
                var lst = model.ProfileIDs.Split(',');
                foreach (var item in lst)
                {
                    t = new Hre_ProfileEntity();
                    Guid _Id = new Guid(item);
                    t.ID = _Id;
                    _temp.Add(t);
                }

                if (model.OrgStructureIDs != null)
                {
                    lstProfileIDs = Actionservices.GetData<Hre_ProfileEntity>(lstObj, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, ref status).ToList();
                    _profileIDs = lstProfileIDs.Where(m => !_temp.Contains(m)).ToList();
                    lstProfileIDs.AddRange(_profileIDs);
                }
                else
                {
                    lstProfileIDs = _temp;
                }
            }
            else
            {
                lstProfileIDs = Actionservices.GetData<Hre_ProfileEntity>(lstObj, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, ref status).ToList();
            }
            #endregion

            var result = CanService.GetMealRecordSummary(model.LineID, model.CateringID, model.CanteenID, dateStart, dateEnd, lstProfileIDs,UserLogin).ToList().Translate<Can_MealRecordModel>();

            if (model.IsExport)
            {
                var fullPath = ExportService.Export(result, model.ValueFields.Split(','));
                return Json(fullPath);
            }

            if (model.selectedIDs != null)
            {
                var strSelect = model.selectedIDs.Split(',');
                List<Guid> lstSelect = new List<Guid>();
                foreach (var item in strSelect)
                {
                    lstSelect.Add(Guid.Parse(item));
                }
                var resultSelect = result.Where(m => lstSelect.Contains(m.ID)).ToList();
                var fullPath = ExportService.Export(resultSelect, model.ValueFields.Split(','));
                return Json(fullPath);
            }

            //request.Page = 1;
            var dataSourceResult = result.ToDataSourceResult(request);
            //dataSourceResult.Total = result.Count() <= 0 ? 0 : result.FirstOrDefault().TotalRow;
            return Json(result.ToDataSourceResult(request));
        }
Esempio n. 19
0
        //[TestMethod]
        public void ExportData()
        {
            using (var context = new VnrHrmDataContext())
            {
                #region Cat_Export
                List<Cat_Export> listExport = new List<Cat_Export>();
                Cat_Export _export = new Cat_Export()
                {
                    Id = 1,
                    ExportName = "Test Export",
                    ExportCode = "Test",
                    ScreenName = "Test Screen",
                    ObjectName = "Hre_Profile",
                    IsReadOnly = true,
                    IsProtected = true,
                    SheetIndex = 1,
                    StartColumnIndex = 1,
                    StartRowIndex = 2,
                    TemplateFile = "Test Template File",
                    IsGroup = true
                };
                listExport.Add(_export);
                #endregion

                #region Cat_ExportItem
                List<Cat_ExportItem> listExportItem = new List<Cat_ExportItem>();
                Cat_ExportItem _exportItemEntity1 = new Cat_ExportItem()
                {
                    ExportID = 1,
                    DataField = "ProfileName",
                    ExcelField = "B"
                };
                Cat_ExportItem _exportItemEntity2 = new Cat_ExportItem()
                {
                    ExportID = 1,
                    DataField = "CodeEmp",
                    ExcelField = "C"
                };
                Cat_ExportItem _exportItemEntity3 = new Cat_ExportItem()
                {
                    ExportID = 1,
                    DataField = "DateHire",
                    ExcelField = "D"
                };
                listExportItem.Add(_exportItemEntity1);
                listExportItem.Add(_exportItemEntity2);
                listExportItem.Add(_exportItemEntity3);
                #endregion

                context.Cat_ExportItem.Add(_exportItemEntity1);
                context.Cat_ExportItem.Add(_exportItemEntity2);
                context.Cat_ExportItem.Add(_exportItemEntity3);
                context.Cat_Export.Add(_export);
                context.SaveChanges();
            }

            string passwordwrite = "123";
            string passwordread = "123";

            string filename = "D:\\New Microsoft Excel Worksheet.xls";
            string templatePath = "D:\\Template";

            #region Datasource
            List<Hre_ProfileEntity> listdataProfile = new List<Hre_ProfileEntity>();
            Hre_ProfileEntity _Profile1 = new Hre_ProfileEntity()
            {
                ProfileName = "Name1",
                CodeEmp = "001",
                DateHire = DateTime.Now
            };
            Hre_ProfileEntity _Profile2 = new Hre_ProfileEntity()
            {
                ProfileName = "Name2",
                CodeEmp = "002",
                DateHire = DateTime.Now
            };
            listdataProfile.Add(_Profile1);
            listdataProfile.Add(_Profile2);
            #endregion

            ExportService service = new ExportService();
            service.ExportByTemplate(1, filename, passwordwrite, passwordread, templatePath, null, listdataProfile);
            Process.Start(filename);
        }
Esempio n. 20
0
        /// <summary>
        /// Hàm Parse công thức ra phần tử và lưu vào list tổng 
        /// </summary>
        /// <param name="formula"></param>
        /// <param name="listElementFormula"></param>
        /// <param name="TotalData"></param>
        /// <param name="profileItem"></param>
        /// <param name="CutOffDuration"></param>
        /// <param name="listTmpDeduction"></param>
        /// <returns></returns>
        public List<ElementFormula> ParseFormula(Cat_ElementEntity formula, List<ElementFormula> listElementFormula, ComputePayrollDataModel TotalData, Hre_ProfileEntity profileItem, Att_CutOffDurationEntity CutOffDuration, Dictionary<Guid, ValueCount> listTmpDeduction)
        {
            string strFormula = formula.Formula.Replace("\n", "").Replace("\t", "").Trim();

            //Các phần tử tính lương tách ra từ 1 chuỗi công thức
            List<string> ListFormula = ParseFormulaToList(strFormula).Where(m => m.IndexOf('[') != -1 && m.IndexOf(']') != -1).ToList();

            //Các phần tử tính lương chưa có kết quả
            List<string> ListFormulaNotValue = ListFormula.Where(m => !listElementFormula.Any(t => t.VariableName == m.Replace("[", "").Replace("]", ""))).ToList();

            //có phần tử chưa được tính trước đó
            if (ListFormulaNotValue != null && ListFormulaNotValue.Count > 0)
            {
                foreach (string elementNotValue in ListFormulaNotValue)
                {

                    //kiểm tra phần tử đó là phần tử Enum hay là phần tử công thức
                    if (TotalData.listElement_All.Any(m => m.GradePayrollID != null && m.ElementCode == elementNotValue.Replace("[", "").Replace("]", "")))//là phần tử công thức
                    {
                        //var tt = TotalData.listElement_All.Where(m => m.ElementCode == elementNotValue.Replace("[", "").Replace("]", "")).FirstOrDefault();
                        listElementFormula = ParseFormula(TotalData.listElement_All.Where(m => m.ElementCode == elementNotValue.Replace("[", "").Replace("]", "")).FirstOrDefault(), listElementFormula, TotalData, profileItem, CutOffDuration, listTmpDeduction);
                    }
                    else//là phần tử enum
                    {
                        listElementFormula = GetStaticValues(TotalData, listElementFormula, profileItem, CutOffDuration, formula.ElementCode, listTmpDeduction);
                    }
                }
            }

            //Do mệnh đề if luôn trả về false nên xử lý riêng cho mệnh đề if ở đây
            //nguyên ngân là do dll CalcEngine, nhưng chưa tìm ra cách giải quyết
            if (formula.Formula.ToUpper().Contains("IF("))
            {
                string _formula = formula.Formula;
                foreach (var i in listElementFormula.Distinct().ToList())
                {
                    if (formula.Formula.Contains("[" + i.VariableName + "]"))
                    {
                        if (i.Value != null)
                        {
                            _formula = _formula.Replace("[" + i.VariableName + "]", i.Value.ToString());
                        }
                        else
                        {
                            i.Value = 0;
                            i.ErrorMessage = "Null";
                            _formula = _formula.Replace("[" + i.VariableName + "]", i.Value.ToString());
                        }
                    }
                }
                var result = FormulaHelper.ParseFormula(_formula.Replace("[", "").Replace("]", ""), listElementFormula.Distinct().ToList());
                listElementFormula.Add(new ElementFormula(formula.ElementCode, result.Value, 0, result.ErrorMessage));
            }
            else
            {
                var result = FormulaHelper.ParseFormula(formula.Formula.Replace("[", "").Replace("]", ""), listElementFormula.Distinct().ToList());
                listElementFormula.Add(new ElementFormula(formula.ElementCode, result.Value, 0, result.ErrorMessage));
            }
            return listElementFormula.Distinct().ToList();
        }
Esempio n. 21
0
 /// <summary>
 /// Cập nhật phòng ban cho nhân viên
 /// </summary>
 /// <param name="SalaryClassName"></param>
 /// <param name="ProfileIDs"></param>
 /// <param name="DateEndProbation"></param>
 /// <param name="DateHire"></param>
 /// <returns></returns>
 public ActionResult UpdateOrgProfile([Bind]Hre_ProfileModel model)
 {
     IList<Hre_ProfileEntity> list = new List<Hre_ProfileEntity>();
     if (!string.IsNullOrEmpty(model.listId))
     {
         List<Guid> lisIDs = model.listId.Split(',').Select(x => Guid.Parse(x)).ToList();
         Hre_ProfileEntity ObjProfile = null;
         var actionService = new ActionService(UserLogin);
         var ProfileService = new Hre_ProfileServices();
         foreach (Guid item in lisIDs)
         {
             string status = string.Empty;
             ObjProfile = new Hre_ProfileEntity();
             var ResultProfile = actionService.GetData<Hre_ProfileEntity>(item, ConstantSql.hrm_hr_sp_get_ProfileById, ref status).FirstOrDefault();
             ObjProfile = ResultProfile;
             ObjProfile.OrgStructureID = model.OrgStructureID;
             ProfileService.Edit(ObjProfile);
             list.Add(ObjProfile);
         }
     }
     return Json(list);
 }
        private List<Att_AnnualDetail> AnalyzeAnnualSickPerProfile(Hre_ProfileEntity Profile, List<Cat_GradeAttendance> lstGradeCfg, List<Att_Grade> lstGrade,
            DateTime BeginYear, DateTime EndYear, List<Att_LeaveDay> lstLeaveSick, List<Att_AnnualDetail> lstAnnualDetailInDB, Att_AnnualLeave AnnualLeave,
            List<Att_Roster> lstRosterInYear, List<Att_RosterGroup> lstRosterGroup, List<Hre_WorkHistory> lstWorkHistory, List<Cat_DayOff> lstDayOff,
            bool IsFrom1To31, List<Cat_Shift> shifts)
        {
            List<Att_AnnualDetail> lstResult = new List<Att_AnnualDetail>();
            double leaveBeginYearToMonth = 0;
            double leaveBeginYearToMonth_Init = 0;
            string E_ROSTERGROUP = RosterType.E_ROSTERGROUP.ToString();
            List<Att_Roster> lstRoster_byProfile = lstRosterInYear.Where(m => m.ProfileID == Profile.ID && m.Type != E_ROSTERGROUP).ToList();
            List<Att_Roster> lstRosterTypeGroup = lstRosterInYear.Where(m => m.ProfileID == Profile.ID && m.Type == E_ROSTERGROUP).ToList();

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

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

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

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

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

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

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

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

        }
Esempio n. 23
0
        public Hre_ProfileModel Post([Bind]Hre_ProfileModel model)
        {
            string status = string.Empty;
            if (model != null)
            {
                ActionService service = new ActionService(UserLogin);
                BaseService BaseService = new BaseService();

                if (!string.IsNullOrWhiteSpace(model.CodeAttendance))
                {
                    model.CodeAttendance = model.CodeAttendance.TrimAll();
                }

                #region Validate

                string message = string.Empty;

                var checkValidate = HRM.Business.Main.Domain.ValidatorService.OnValidateData<Hre_ProfileModel>(model, "Hre_Profile", ref message);
                if (!checkValidate)
                {
                    model.ActionStatus = message;
                    return model;
                }
                if (model.DateOfEffectOld != null)
                {
                    checkValidate = HRM.Business.Main.Domain.ValidatorService.OnValidateData<Hre_ProfileModel>(model, "Hre_ProfileCheckDateOfEffect", ref message);
                    if (!checkValidate)
                    {
                        model.ActionStatus = message;
                        return model;
                    }
                }
                #endregion

                #region Xử lý cập nhật AbilityTitle khi chọn rank

                if (model.SalaryClassID != null)
                {
                    var abilityTitleBySalaryClass = BaseService.GetData<Cat_AbilityTileEntity>(Common.DotNetToOracle(model.SalaryClassID.ToString()), ConstantSql.hrm_cat_sp_get_AbilityTileBySalaryClassId, UserLogin, ref status).FirstOrDefault();
                    if (abilityTitleBySalaryClass != null)
                    {
                        model.AbilityTileID = abilityTitleBySalaryClass.ID;
                    }
                }

                #endregion

                #region Xử Lý Lưu field DateOfBirth
                var dateOfBirth = string.Empty;
                if (model.DayOfBirth == 00 && model.MonthOfBirth == 00)
                {
                    model.ActionStatus = "ErrorDateOfBirth";
                    return model;
                }
                if (model.DayOfBirth == null && model.MonthOfBirth == null && model.YearOfBirth == null)
                {
                    dateOfBirth = string.Empty;

                }
                else
                {
                    if (model.DayOfBirth == null)
                    {
                        model.DayOfBirth = DateTime.Now.Day;
                    }
                    if (model.MonthOfBirth == null)
                    {
                        model.MonthOfBirth = DateTime.Now.Month;
                    }
                    if (model.YearOfBirth == null)
                    {
                        model.ActionStatus = "ErrorDateOfBirth";
                        return model;
                    }
                }


                if (model.DayOfBirth >= 0 || model.MonthOfBirth >= 0 || model.YearOfBirth >= 0)
                {
                    if (model.DayOfBirth == 30 && model.MonthOfBirth == 2)
                    {
                        model.ActionStatus = "ErrorDateOfBirth";
                        return model;
                    }
                    if (model.DayOfBirth == 31 && model.MonthOfBirth == 2)
                    {
                        model.ActionStatus = "ErrorDateOfBirth";
                        return model;
                    }
                    if (model.DayOfBirth > 31 || model.MonthOfBirth > 12)
                    {
                        model.ActionStatus = "ErrorDateOfBirth";
                        return model;
                    }
                    dateOfBirth = model.MonthOfBirth + "/" + model.DayOfBirth + "/" + model.YearOfBirth;

                }

                model.DateOfBirth = string.IsNullOrEmpty(dateOfBirth) ? (DateTime?)null : DateTime.Parse(dateOfBirth);
                #endregion
                Hre_ProfileModel HreProfile = new Hre_ProfileModel();
                if (model.ID != Guid.Empty)
                {
                    HreProfile = GetById(model.ID);
                }
                if (HreProfile != null && (model.ID == HreProfile.ID) && model.ActionStatus != "1")
                {
                    string[] listFieldName = new[] { "JobTitleID", "PositionID", "EmpTypeID", "DateOfEffect", "CostCentreID", "OrgStructureID", "WorkPlaceID", "SupervisorID" };
                    foreach (var item in listFieldName)
                    {
                        var value1 = model.GetPropertyValue(item);
                        var value2 = HreProfile.GetPropertyValue(item);
                        if ((value1 != null && value2 != null) && (value1.ToString() != value2.ToString()))
                        {
                            model.SetPropertyValue(Constant.ActionStatus, NotificationType.Change.ToString());
                            return model;
                        }
                    }
                    if (HreProfile.ProfileName != model.ProfileName)
                    {
                        if (model.ProfileName.Contains(' '))
                        {
                            model.FirstName = model.ProfileName.Substring(model.ProfileName.LastIndexOf(' ') + 1);
                            model.NameFamily = model.ProfileName.Substring(0, model.ProfileName.LastIndexOf(' '));
                        }
                        else
                        {
                            model.FirstName = model.ProfileName;
                        }
                    }
                }
                if (model.ActionStatus == "1" || model.ActionStatus == "Success" || string.IsNullOrEmpty(model.ActionStatus))
                {

                    var serviceAddress = new Hre_AddressServices();
                    var serviceProfile = new Hre_ProfileServices();
                    var profileEntity = new Hre_ProfileEntity();
                    if (model.ID != Guid.Empty)
                    {
                        profileEntity = serviceProfile.GetData<Hre_ProfileEntity>(Common.DotNetToOracle(model.ID.ToString()), ConstantSql.hrm_hr_sp_get_ProfileById, UserLogin, ref status).FirstOrDefault();
                    }

                    #region Xử lý lưu CardCode
                    Hre_CardHistoryServices cardservices = new Hre_CardHistoryServices();
                    Hre_WorkHistoryServices workHistoryservices = new Hre_WorkHistoryServices();

                    if (profileEntity != null && model.CodeAttendance != null && model.DateApplyAttendanceCode != null && (model.CodeAttendance != profileEntity.CodeAttendance
                    || model.DateApplyAttendanceCode != profileEntity.DateApplyAttendanceCode))
                    {
                        // Chỉ thay đổi mã chấm công
                        if (model.DateApplyAttendanceCode == profileEntity.DateApplyAttendanceCode && model.CodeAttendance != profileEntity.CodeAttendance)
                        {
                            Hre_CardHistoryEntity history = cardservices.GetData<Hre_CardHistoryEntity>(Common.DotNetToOracle(model.ID.ToString()), ConstantSql.hrm_hr_sp_get_CardHistoryByProfileId, UserLogin, ref status).OrderByDescending(s => s.DateEffect).FirstOrDefault();
                            if (history != null)
                            {
                                history.CardCode = model.CodeAttendance;
                                cardservices.Edit(history);
                            }
                            else
                            {
                                history = new Hre_CardHistoryEntity();
                                history.ProfileID = model.ID;
                                history.CardCode = model.CodeAttendance;
                                history.DateEffect = model.DateApplyAttendanceCode;
                                cardservices.Add(history);
                            }
                        }
                        // Chỉ thay đổi Ngày áp dụng mã chấm công

                        else if (model.CodeAttendance == profileEntity.CodeAttendance && model.DateApplyAttendanceCode != profileEntity.DateApplyAttendanceCode)
                        {
                            if (model.DateApplyAttendanceCode < profileEntity.DateApplyAttendanceCode)
                            {
                                model.StatusVerify = "Invalid";
                                return model;
                            }
                            Hre_CardHistoryEntity history = cardservices.GetData<Hre_CardHistoryEntity>(Common.DotNetToOracle(model.ID.ToString()), ConstantSql.hrm_hr_sp_get_CardHistoryByProfileId, UserLogin, ref status).OrderByDescending(s => s.DateEffect).FirstOrDefault();
                            if (history != null)
                            {
                                history.DateEffect = model.DateApplyAttendanceCode;
                                cardservices.Edit(history);
                            }
                            else
                            {
                                history = new Hre_CardHistoryEntity();
                                history.ProfileID = model.ID;
                                history.CardCode = model.CodeAttendance;
                                history.DateEffect = model.DateApplyAttendanceCode;
                                cardservices.Add(history);
                            }
                        }
                    }
                    // Tạo mới NV hoặc thay đổi cả 2( mã chấm công + ngày hiệu lực)
                    Hre_CardHistoryEntity cardhistory = null;
                    if (model != null && model.ID == Guid.Empty || (model != null && profileEntity != null && model.CodeAttendance != profileEntity.CodeAttendance
                                && model.DateApplyAttendanceCode != profileEntity.DateApplyAttendanceCode))
                    {
                        cardhistory = new Hre_CardHistoryEntity();
                        cardhistory.ProfileID = model.ID;
                        cardhistory.CardCode = model.CodeAttendance;
                        cardhistory.DateEffect = model.DateApplyAttendanceCode;
                    }
                    #endregion

                    #region Xử lý lưu quá trình công tác
                    Hre_WorkHistoryEntity workHistory = null;
                    if (model != null && (model.JobTitleID != profileEntity.JobTitleID || model.PositionID != profileEntity.PositionID || model.EmpTypeID != profileEntity.EmpTypeID ||
                        (model.DateOfEffect != null && profileEntity.DateOfEffect != null &&
                        model.DateOfEffect.Value.ToString() != profileEntity.DateOfEffect.Value.ToString())
                        || model.CostCentreID != profileEntity.CostCentreID || model.SupervisorID != profileEntity.SupervisorID
                        || model.OrgStructureID != profileEntity.OrgStructureID || model.WorkPlaceID != profileEntity.WorkPlaceID))
                    {

                        workHistory = new Hre_WorkHistoryEntity();
                        var orgService = new Cat_OrgStructureServices();
                        var jobtitleService = new Cat_JobTitleServices();
                        var postitionService = new Cat_PositionServices();
                        var workPlaceService = new Cat_WorkPlaceServices();

                        workHistory.CostCentreID = model.CostCentreID;
                        workHistory.OrganizationStructureID = model.OrgStructureID;
                        workHistory.PositionID = model.PositionID;
                        workHistory.JobTitleID = model.JobTitleID;
                        workHistory.SalaryClassID = model.SalaryClassID;
                        workHistory.CostSourceID = model.CostSourceID;
                        workHistory.AbilityTileID = model.AbilityTileID;
                        if (profileEntity != null)
                        {
                            var orgStructureOld = new Cat_OrgStructureEntity();
                            if (profileEntity.OrgStructureID != null && profileEntity.OrgStructureID != Guid.Empty)
                            {
                                orgStructureOld = orgService.GetData<Cat_OrgStructureEntity>(profileEntity.OrgStructureID, ConstantSql.hrm_cat_sp_get_OrgStructureById, UserLogin, ref status).FirstOrDefault();
                            }
                            var jobtitleOld = new Cat_JobTitleEntity();
                            if (profileEntity.JobTitleID != null && profileEntity.JobTitleID != Guid.Empty)
                            {
                                jobtitleOld = jobtitleService.GetData<Cat_JobTitleEntity>(profileEntity.JobTitleID, ConstantSql.hrm_cat_sp_get_HDTJobTypeById, UserLogin, ref status).FirstOrDefault();
                            }
                            var postitionOld = new Cat_PositionEntity();
                            if (profileEntity.PositionID != null && profileEntity.PositionID != Guid.Empty)
                            {
                                postitionOld = postitionService.GetData<Cat_PositionEntity>(profileEntity.PositionID, ConstantSql.hrm_cat_sp_get_PositionById, UserLogin, ref status).FirstOrDefault();
                            }
                            var workPlace = new Cat_WorkPlaceEntity();
                            if (model.WorkPlaceID != null && model.WorkPlaceID != Guid.Empty)
                            {
                                workPlace = workPlaceService.GetData<Cat_WorkPlaceEntity>(model.WorkPlaceID, ConstantSql.hrm_cat_sp_get_WorkPlaceById, UserLogin, ref status).FirstOrDefault();
                            }
                            var workPlaceOld = new Cat_WorkPlaceEntity();
                            if (profileEntity.WorkPlaceID != null && profileEntity.WorkPlaceID != Guid.Empty)
                            {
                                workPlaceOld = workPlaceService.GetData<Cat_WorkPlaceEntity>(profileEntity.WorkPlaceID, ConstantSql.hrm_cat_sp_get_WorkPlaceById, UserLogin, ref status).FirstOrDefault();
                            }
                            workHistory.OrgOld = orgStructureOld != null ? orgStructureOld.OrgStructureName : "";
                            workHistory.JobTitleOld = jobtitleOld != null ? jobtitleOld.JobTitleName : "";
                            workHistory.PositionOld = postitionOld != null ? postitionOld.PositionName : "";
                            workHistory.WorkLocation = workPlace != null ? workPlace.WorkPlaceName : "";
                            workHistory.WorkLocationOld = workPlaceOld != null ? workPlaceOld.WorkPlaceName : "";
                        }
                        if (workHistory.ID == Guid.Empty)
                        {
                            if (model.DateOfEffect != null)
                            {
                                workHistory.DateEffective = model.DateOfEffect.Value;
                            }
                            else
                            {
                                workHistory.DateEffective = DateTime.Now;
                            }
                        }

                        if (model.DateQuit != null && (profileEntity == null || profileEntity.DateQuit != model.DateQuit))
                        {
                            workHistory.DateEffective = model.DateQuit.Value;
                        }
                    }

                    #region Ngày hiệu lực phải <= ngày hiện tại thì mới cập nhật lại quá trình công tác
                    if (model.DateOfEffect > DateTime.Now && profileEntity != null && profileEntity.DateOfEffect != null)
                    {
                        model.DateOfEffect = profileEntity.DateOfEffect;
                        model.OrgStructureID = profileEntity.OrgStructureID;
                        model.ShopID = profileEntity.ShopID;
                        model.JobTitleID = profileEntity.JobTitleID;
                        model.PositionID = profileEntity.PositionID;
                        model.SupervisorID = profileEntity.SupervisorID;
                        model.HighSupervisorID = profileEntity.HighSupervisorID;
                        model.IsHeadDept = profileEntity.IsHeadDept;
                        model.EmpTypeID = profileEntity.EmpTypeID;
                        model.LaborType = profileEntity.LaborType;
                        model.SikillLevel = profileEntity.SikillLevel;
                        model.PayrollGroupID = profileEntity.PayrollGroupID;
                        model.SalaryClassID = profileEntity.SalaryClassID;
                        model.CostCentreID = profileEntity.CostCentreID;
                        model.LocationCode = profileEntity.LocationCode;
                        model.WorkPlaceID = profileEntity.WorkPlaceID;
                    }
                    #endregion

                    #endregion

                    var profileModel = service.UpdateOrCreate<Hre_ProfileEntity, Hre_ProfileModel>(model);

                    if (cardhistory != null && profileModel != null)
                    {
                        cardhistory.ProfileID = profileModel.ID;
                        cardservices.Add(cardhistory);
                    }

                    if (workHistory != null && profileModel != null)
                    {
                        workHistory.EmployeeTypeID = profileModel.EmpTypeID;
                        workHistory.ProfileID = profileModel.ID;
                        workHistoryservices.Add(workHistory);
                    }
                }
            }

            //Xóa cache lưu lại của cây phòng ban
            HttpContext.Current.Cache.Remove("List_OrgStructureTreeView");
            HttpContext.Current.Cache.Remove("List_OrgStructureTreeViewSumProfile");

            return model;
        }