/// <summary>Hàm tính lương và mức đóng của BHXH,BHYT,BHTN</summary> /// <param name="lstProfile"></param> /// <param name="lstSalInsByProfile"></param> /// <param name="endMonthCheck">Cuối tháng kiểm tra</param> /// <param name="orgs"></param> /// <param name="contracts"></param> private void SetMoneyInsuranceByProfileByMonth(List<Hre_ProfileEntity> lstProfile, List<Sal_InsuranceSalary> lstSalInsByProfile , DateTime endMonthCheck, string orgs, List<Hre_Contract> contracts,string userLogin) { /* * Goal(Lấy tiền đóng bảo hiểm) * Steps : * - Step1 : Lấy mức trần đóng bảo hiểm (theo ngày hiệu lực mới nhất) * - Step2 : Lấy lương tối thiểu (theo ngày hiệu lực mới nhất) * - Step3 : Lấy tỉ lệ bảo hiểm với ngày áp dụng trước ngày kiểm tra * - Step4 : Lấy lương bảo hiểm của nv (bảng Sal_InsuranceSalary) với ngày ap dụng trước ngày ktra * - Step5 : Cách lấy tiền bảo hiểm ([tienbaohiem]) * - Step5.1 : If so tien(trong sal_insuranceSalary) >= mức trần -> [tienbaohiem] = [MucTran] * - Step5.2 : If so tien(trong sal_insuranceSalary) <= lương tối thiểu -> [tienbaohiem] = [LuongToiThieu] * - Step6 : [tienbaohiem]= [tienbaohiem]+ [PhuCapDieuChinh]+ [tiền HDTJob] */ using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)(new UnitOfWork(context)); string status = string.Empty; var hdt4Amount = 0.0; var hdt5Amount = 0.0; List<Guid> lstProfileIDs = lstProfile.Select(m => m.ID).ToList(); String typeInsurance = ExchangeRateType.E_RATE_SOCIALINSURANCE.ToString(); var lstRateInsurance = unitOfWork.CreateQueryable<Cat_ExchangeRate>(Guid.Empty, m => m.Type == typeInsurance && m.MonthOfEffect <= endMonthCheck).OrderByDescending(al => al.MonthOfEffect).ToList(); String statusInsCape = ValueEntityType.E_INSURANCE_CAPE_AMOUNT.ToString(); String statusMinumunSal = ValueEntityType.E_MINIMUM_SALARY.ToString(); var lstMaxMinSalary = unitOfWork.CreateQueryable<Cat_ValueEntity>(Guid.Empty, m => (m.IsDelete == null || m.IsDelete == false) && (m.Type == statusInsCape || m.Type == statusMinumunSal)).ToList(); #region lay phu cap phat sinh List<object> unusualAllowancePara = new List<object>(); unusualAllowancePara.AddRange(new object[9]); unusualAllowancePara[7] = 1; unusualAllowancePara[8] = Int32.MaxValue - 1; var lstUnusualAllowance = GetData<Sal_UnusualAllowanceEntity>(unusualAllowancePara, ConstantSql.hrm_sal_sp_get_UnusualED,userLogin, ref status).Translate<Sal_UnusualAllowance>() .Where(m => (m.IsDelete == null || m.IsDelete == false) && lstProfileIDs.Contains(m.ProfileID)) .ToList(); #endregion #region lay ds jobTitle var jobTitles = unitOfWork.CreateQueryable<Cat_JobTitle>(Guid.Empty, m => m.IsDelete == null).ToList(); #endregion #region lay ds Cat_region var Regions = unitOfWork.CreateQueryable<Cat_Region>(Guid.Empty).ToList(); #endregion var lstUnusualAllowanceCfg = unitOfWork.CreateQueryable<Cat_UnusualAllowanceCfg>(Guid.Empty).ToList(); #region Lay số tiền HDT4 vã HDT5 theo timeline //Tại Cat_UnusualAllowanceCfg thiết lập Phụ cấp có mã: HDT4, HDT5 //Tại Cat_UnAllowCfgAmount thiết lập Timeline cho mức HDT4 và HDT5 với mức hưởng tương ứng //Mong muốn: Lấy mức hưởng theo timeline để tính HDT Job cho Bảo hiểm const string HDT4 = "HDT4"; const string HDT5 = "HDT5"; var unAllowCfgAmount = unitOfWork.CreateQueryable<Cat_UnAllowCfgAmount>(Guid.Empty, p => p.Cat_UnusualAllowanceCfg != null && (p.Cat_UnusualAllowanceCfg.Code == HDT4 || p.Cat_UnusualAllowanceCfg.Code == HDT5) && (p.FromDate <= endMonthCheck && endMonthCheck <= p.ToDate)).ToList(); hdt4Amount = unAllowCfgAmount.Where(p => p.Cat_UnusualAllowanceCfg != null && p.Cat_UnusualAllowanceCfg.Code == HDT4).Select(p => p.Amount ?? 0).FirstOrDefault(); hdt5Amount = unAllowCfgAmount.Where(p => p.Cat_UnusualAllowanceCfg != null && p.Cat_UnusualAllowanceCfg.Code == HDT5).Select(p => p.Amount ?? 0).FirstOrDefault(); #endregion //lấy mức trần bảo hiểm theo ngày hiệu lực List<Cat_ValueEntity> listMaxSalary = lstMaxMinSalary.Where(val => val.Type == statusInsCape) .OrderByDescending(pit => pit.DateOfEffect) .ToList(); //lấy lương tối thiểu theo ngày hiệu lực List<Cat_ValueEntity> listMinSalary = lstMaxMinSalary.Where(val => val.Type == statusMinumunSal) .OrderByDescending(pit => pit.DateOfEffect).ToList(); //lấy tỉ lệ bảo hiểm với ngày áp dụng trước ngày kiểm tra var lstInsRate = unitOfWork.CreateQueryable<Cat_RateInsurance>(Guid.Empty, m => m.ApplyFrom <= endMonthCheck).ToList(); var orgTypes = unitOfWork.CreateQueryable<Cat_OrgStructureType>(Guid.Empty, s => s.OrgStructureTypeCode == OrgUnit.E_DEPARTMENT.ToString()).ToList(); #region lay ds HDTJOb List<object> hdtJobPara = new List<object>(); hdtJobPara.AddRange(new object[14]); hdtJobPara[0] = null; hdtJobPara[1] = null; hdtJobPara[2] = null; hdtJobPara[3] = null; hdtJobPara[4] = null; hdtJobPara[5] = orgs; hdtJobPara[6] = null; hdtJobPara[7] = null; hdtJobPara[8] = null; hdtJobPara[9] = null; hdtJobPara[10] = null; hdtJobPara[11] = null; hdtJobPara[12] = 1; hdtJobPara[13] = int.MaxValue - 1; var hreHDTJobs = GetData<Hre_HDTJobEntity>(hdtJobPara, ConstantSql.hrm_hr_sp_get_HDTJob,userLogin, ref status).Translate<Hre_HDTJob>().ToList(); hreHDTJobs = hreHDTJobs.Where(p => p.DateTo.HasValue && p.DateTo.Value.Month == endMonthCheck.Month && p.DateTo.Value.Year == endMonthCheck.Year).ToList(); //var hreHDTJobs = repoHreHDTJob.FindBy(p => p.IsDelete == null && lstProfileIDs.Contains(p.ProfileID ?? Guid.Empty)).ToList(); #endregion #region Lay che do luong //lay ds sal_grade List<object> salGradePara = new List<object>(); salGradePara.AddRange(new object[7]); salGradePara[0] = null; salGradePara[1] = null; salGradePara[2] = null; salGradePara[3] = null; salGradePara[4] = null; salGradePara[5] = 1; salGradePara[6] = 50000; var salGrade = GetData<Sal_Grade>(salGradePara, ConstantSql.hrm_sal_sp_get_Sal_Grade,userLogin, ref status) .Where(p => p.IsDelete == null && lstProfileIDs.Contains(p.ProfileID) && p.MonthStart.HasValue && p.MonthStart <= endMonthCheck).ToList(); //var salGrade = repoSalGrade.FindBy(p => p.IsDelete == null && lstProfileIDs.Contains(p.ProfileID) && p.MonthStart.HasValue // && p.MonthStart <= monthCheck).ToList(); var catGradePayroll = new List<Cat_GradePayroll>(); var cat_SalaryClasses = unitOfWork.CreateQueryable<Cat_SalaryClass>(Guid.Empty).ToList(); var orgStructures = unitOfWork.CreateQueryable<Cat_OrgStructure>(Guid.Empty).ToList(); var hdtJobGroups = unitOfWork.CreateQueryable<Cat_HDTJobGroup>(Guid.Empty).ToList(); if (salGrade.Any()) { var catGradePayrollIds = salGrade.Select(p => p.GradePayrollID).ToList(); catGradePayroll = unitOfWork.CreateQueryable<Cat_GradePayroll>(Guid.Empty, p => catGradePayrollIds.Contains(p.ID)).ToList(); } #endregion var cutOffDuration = new Att_CutOffDuration(); if (hreHDTJobs.Any()) { cutOffDuration = unitOfWork.CreateQueryable<Att_CutOffDuration>(Guid.Empty, p => p.MonthYear.Year == endMonthCheck.Year && p.MonthYear.Month == endMonthCheck.Month).FirstOrDefault(); if (cutOffDuration == null) { cutOffDuration = new Att_CutOffDuration { DateStart = new DateTime(1970, 1, 1), DateEnd = new DateTime(1970, 1, 1), MonthYear = new DateTime(1970, 1, 1) }; } } List<Cat_Element> listElementFormulaDB = unitOfWork.CreateQueryable<Cat_Element>(Guid.Empty).ToList(); //tham giam bao hiem var joinInsurance = false; foreach (var profile in lstProfile) { if (profile.IsHaveInsSocial != true && profile.IsHaveInsHealth != true && profile.IsHaveInsUnEmp != true) { joinInsurance = false; // continue; } else { joinInsurance = true; } var salInsByProfile = lstSalInsByProfile.Where(m => m.ProfileID == profile.ID && m.DateEffect <= endMonthCheck).OrderByDescending(m => m.DateEffect).FirstOrDefault(); if (salInsByProfile == null) { salInsByProfile = new Sal_InsuranceSalary { InsuranceAmount = 0, }; } double salInsurance = GetInsuranceSalary(endMonthCheck, salInsByProfile, lstRateInsurance, listMaxSalary, listMinSalary); #region lấy tiền HDTJob theo profile và monthCheck //Todo: lấy tiền HDTJob (sử dụng công thức) //lay grade var grade = salGrade.FirstOrDefault(p => p.ProfileID == profile.ID); var gradePayroll = catGradePayroll.FirstOrDefault(p => grade != null && p.ID == grade.GradePayrollID); var hdtJobMoney = 0.0; if (gradePayroll != null && !string.IsNullOrEmpty(gradePayroll.FormulaSalaryIns)) { Hre_HDTJob hreHdtJobProfile; FormulaHelper.FormulaHelperModel result; GetAllowanceInsuranceByFomular(salInsurance, endMonthCheck, hreHDTJobs, cutOffDuration, profile, gradePayroll, out hreHdtJobProfile, out result, lstUnusualAllowanceCfg, lstUnusualAllowance, listElementFormulaDB, hdt4Amount, hdt5Amount); if (result != null && result.Value != null) { double.TryParse(result.Value.ToString(), out hdtJobMoney); } #region Generate tên công việc dựa vào tiền HDTJOb FormulaHelper.FormulaHelperModel resultJobName; var jobtitleName = string.Empty; var jobTitleObj = jobTitles.Where(p => p.ID == profile.JobTitleID).FirstOrDefault(); if (jobTitleObj != null) { jobtitleName = jobTitleObj.JobTitleName; } string hdtJobGroupCode = string.Empty; GetJobNameByFomular(hdtJobMoney, cat_SalaryClasses, hdtJobGroups, hreHdtJobProfile, profile, orgStructures, orgTypes, jobtitleName, gradePayroll, out resultJobName, listElementFormulaDB, out hdtJobGroupCode); string jobName = string.Empty; if (resultJobName != null && resultJobName.Value != null) { jobName = resultJobName.Value.ToString(); } profile.JobName = jobName; profile.HDTJobGroupCode = hdtJobGroupCode; #endregion } #endregion if (hdtJobMoney > 0) { profile.AmountHDTIns = hdtJobMoney; } profile.MoneyInsuranceTotal = (float)salInsurance + hdtJobMoney; profile.MoneyInsuranceHealthTotal = (float)salInsurance + hdtJobMoney; //profile.MoneyInsuranceUnEmpTotal = (float)salInsurance + hdtJobMoney; var regionByProfile = Regions.Where(m => m.ID == profile.RegionID).FirstOrDefault(); if (regionByProfile != null && regionByProfile.MaxSalary != null) { //Todo: Code đang thiếu vì cái minimum của cái nơi đóng bảo hiểm Ps. Chờ Sơn build cái field cần thiết profile.MoneyInsuranceUnEmpTotal = getMonneyBHTN(regionByProfile.MaxSalary.Value, salInsByProfile.InsuranceAmount ?? 0) + hdtJobMoney; } else { profile.MoneyInsuranceUnEmpTotal = (float)salInsurance + hdtJobMoney; } Cat_RateInsurance rateInsurance = GetInsuranceRate(endMonthCheck, lstInsRate); #region [Tung.Ly ] Lấy các phu cấp từ lương bảo hiểm (sal_insuranceSalary) var contract = contracts.Where(p => p.ProfileID == profile.ID).OrderByDescending(p => p.DateUpdate).FirstOrDefault(); if (contract != null && joinInsurance == true) { profile.Allowance1 = contract.Allowance1 ?? 0; profile.Allowance2 = contract.Allowance2 ?? 0; profile.Allowance3 = contract.Allowance3 ?? 0; profile.Allowance4 = contract.Allowance4 ?? 0; profile.AmountChargeIns = profile.Allowance1 + profile.Allowance2 + profile.Allowance3 + profile.Allowance4 + profile.MoneyInsuranceTotal; } #endregion if (profile.IsHaveInsSocial == true) { //tong ti le BHXH do NSDLĐ và NLĐ đóng double rate = (rateInsurance.SocialInsCompRate + rateInsurance.SocialInsEmpRate); profile.MoneyInsuranceSocial = (float)(profile.MoneyInsuranceTotal * rate); #region [Tung.Ly ]: ti le BHXH cty dong va ti le BHXH nv dong //Ti lệ BHXH do cty đóng profile.SocialInsComRate = (rateInsurance.SocialInsCompRate); //Tỉ lệ BHXH do NV đóng profile.SocialInsEmpRate = (rateInsurance.SocialInsEmpRate); //Số tiền BHXH do cty đóng profile.SocialInsComAmount = (double)(profile.MoneyInsuranceTotal * profile.SocialInsComRate); //số tiền BHXH do NV đóng profile.SocialInsEmpAmount = (double)(profile.MoneyInsuranceTotal * profile.SocialInsEmpRate); #endregion } if (profile.IsHaveInsHealth == true) { //Tổng tỉ lệ BHYT do NSDLĐ và NLĐ đóng double rate = (rateInsurance.HealthInsCompRate + rateInsurance.HealthInsEmpRate); profile.MoneyInsuranceHealth = (float)(profile.MoneyInsuranceHealthTotal * rate); #region [Tung.Ly ]: ti le BHYT cty dong va ti le BHXH nv dong //Ti lệ BHYT do cty đóng profile.HealthInsComRate = (rateInsurance.HealthInsCompRate); //Tỉ lệ BHYT do NV đóng profile.HealthInsEmpRate = (rateInsurance.HealthInsEmpRate); //Số tiền BHYT do cty đóng profile.HealthInsComAmount = (double)(profile.MoneyInsuranceHealthTotal * profile.HealthInsComRate); //số tiền BHYT do NV đóng profile.HealthInsEmpAmount = (double)(profile.MoneyInsuranceHealthTotal * profile.HealthInsEmpRate); #endregion } if (profile.IsHaveInsUnEmp == true) { //Tổng tỉ lệ BHTN do NSDLĐ và NLĐ đóng double rate = (rateInsurance.UnemployInsCompRate + rateInsurance.UnemployInsEmpRate); profile.MoneyInsuranceUnEmp = (float)(profile.MoneyInsuranceUnEmpTotal * rate); #region [Tung.Ly ]: ti le BHTN cty dong va ti le BHXH nv dong //Ti lệ BHTN do cty đóng profile.UnemployComRate = (rateInsurance.UnemployInsCompRate); //Tỉ lệ BHTN do NV đóng profile.UnemployEmpRate = (rateInsurance.UnemployInsEmpRate); //Số tiền BHTN do cty đóng profile.UnemployComAmount = (double)(profile.MoneyInsuranceUnEmpTotal * profile.UnemployComRate); //số tiền BHTN do NV đóng profile.UnemployEmpAmount = (double)(profile.MoneyInsuranceUnEmpTotal * profile.UnemployEmpRate); #endregion } } } }
/// <summary> Lấy lương bảo hiểm </summary> /// <param name="monthYear"></param> /// <param name="InsuranceSalary"></param> /// <param name="lstRateIns"></param> /// <param name="lstInsuranceAmountCeiling">mức trần bảo hiểm theo ngày hiệu lực</param> /// <param name="lstInsAmountMinimum">lấy lương tối thiểu theo ngày hiệu lực</param> /// <returns></returns> private Double GetInsuranceSalary(DateTime monthYear, Sal_InsuranceSalary InsuranceSalary, List<Cat_ExchangeRate> lstRateIns, List<Cat_ValueEntity> lstInsuranceAmountCeiling, List<Cat_ValueEntity> lstInsAmountMinimum) { /* * Goal(lay luong bao hiem ) * Steps : * Step1 : Lấy [LuongBaoHiem] (Sal_InsuranceSalary) * Step2 : Nếu [LuongBaoHiem] >= [MucTran] => lay [MucTran] * Step3 : Nếu [LuongBaoHiem] <= [LuongToiThieu] => lay [LuongToiThieu] */ Double result = 0; // DateTime date = DateTime.MinValue; Cat_Currency curIns = null; //Lay muc tran tai thoi diem monthYear => VND Double amountCeilingLasted = GetMaxMinAmountOfMonth(monthYear, lstInsuranceAmountCeiling); //Lay luong toi thieu tai thoi diem monthYear => VND Double amountMinimumSalary = GetMaxMinAmountOfMonth(monthYear, lstInsAmountMinimum); // date = InsuranceSalary.DateEffect ?? monthYear; //tiền tệ curIns = InsuranceSalary.Cat_Currency; result = InsuranceSalary.InsuranceAmount ?? 0; lstRateIns = lstRateIns.Where(rate => rate.MonthOfEffect <= monthYear).ToList(); if (curIns != null && curIns.Code != CurrencyCode.VND.ToString() && lstRateIns.Any()) { result = ConvertExtractRateToVND(result, curIns, lstRateIns); } if (result >= amountCeilingLasted) { result = amountCeilingLasted; } if (result <= amountMinimumSalary && result > 0) { result = amountMinimumSalary; } return result; }