using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.Common; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using Wellan.Common; using Wellan.Data; /// /// 計算勞保費 /// public class Blif : LaborAndHealthFee { private int _inWorkDays; private int _insuranceSalary; private int _injurySalary; private decimal _normalPersonalFee; private decimal _normalCompanyFee; private decimal _lostJobPersonalFee; private decimal _lostJobCompanyFee; private decimal _injuryCompanyFee; private decimal _disableNormalSupport; private decimal _disableLostJobSupport; private decimal _salaryReverseFund; private double _normalFeeRate; private double _lostJobFeeRate; private double _salaryReverseFundRate; private double _injuryCompanyFeeRate; // 職災級距表 private Dictionary> _bljiAmtData; public Blif(DateTime aDate) : base(aDate) { _bftyp = 1; _tableName = "BLIF"; } /// /// 普通事故費率 /// public double NormalFeeRate { get { return _normalFeeRate; } set { _normalFeeRate = value; } } /// /// 就業保險費率 /// public double LostJobFeeRate { get { return _lostJobFeeRate; } set { _lostJobFeeRate = value; } } /// /// 工資墊償基金費率 /// public double SalaryReverseFundRate { get { return _salaryReverseFundRate; } set { _salaryReverseFundRate = value; } } /// /// 職災保險費率 /// public double InjuryFeeRate { get { return _injuryCompanyFeeRate; } set { _injuryCompanyFeeRate = value; } } public LaborInsuranceFee GetFee() { LaborInsuranceFee fee = new LaborInsuranceFee(); fee.Init(); fee.InWorkDays = _inWorkDays; fee.InsuranceSalary = _insuranceSalary; fee.InjurySalary = _injurySalary; fee.NormalPersonalFee = _normalPersonalFee; fee.NormalCompanyFee = _normalCompanyFee; fee.LostJobPersonalFee = _lostJobPersonalFee; fee.LostJobCompanyFee = _lostJobCompanyFee; fee.InjuryCompanyFee = _injuryCompanyFee; fee.DisableNormalSupport = _disableNormalSupport; fee.DisableLostJobSupport = _disableLostJobSupport; fee.SalaryReverseFund = _salaryReverseFund; return fee; } public void Clear() { _inWorkDays = 0; _insuranceSalary = 0; _injurySalary = 0; _normalPersonalFee = 0; _normalCompanyFee = 0; _lostJobPersonalFee = 0; _lostJobCompanyFee = 0; _injuryCompanyFee = 0; _disableNormalSupport = 0; _disableLostJobSupport = 0; _salaryReverseFund = 0; } /// /// 取得職災級距表 /// /// 日期 private void GetBLJIData(DateTime aDate) { if (this._bljiAmtData == null) _bljiAmtData = new Dictionary>(); if (!_bljiAmtData.ContainsKey(aDate)) { List _newAmtDataItem = new List(); // 取得適用級距表版本 DataTable _verData = _query.Select("SELECT * FROM BFDT WHERE BFTYP=4 ORDER BY BFVER"); int version = 0; foreach (System.Data.DataRow row in _verData.Rows) { if (aDate.CompareTo(row["BFSDT"]) >= 0 && (row["BFEDT"] == DBNull.Value || aDate.CompareTo(row["BFEDT"]) <= 0)) { version = Convert.ToInt32(row["BFVER"]); break; } } // 取得該版本的級距表 DataTable data = _query.Select(String.Format("SELECT * FROM BLJI WHERE BSVER={0} ORDER BY BSLVL", version)); for (int i = 0; i < data.Rows.Count; i++) { _newAmtDataItem.Add(new LHFClass(Convert.ToInt32(data.Rows[i]["BSLOW"]), Convert.ToInt32(data.Rows[i]["BSHIH"]), Convert.ToInt32(data.Rows[i]["BSAMT"]))); } _bljiAmtData.Add(aDate, _newAmtDataItem); } } /// /// 取得職災保險投保薪資 /// /// 日期 /// 薪資 /// protected double GetBLJIAmt(DateTime aDate, int salary) { GetBLJIData(aDate); double bsamt = 0; for (int i = 0; i < _amtData[aDate].Count; i++) { if (salary >= _amtData[aDate][i].Low && salary <= _amtData[aDate][i].High) { bsamt = _amtData[aDate][i].Amt; break; } } return bsamt; } /// /// 取得職災保險投保薪資 /// /// 薪資 /// protected double GetBLJIAmt(int salary) { return GetBLJIAmt(_baseDate, salary); } /// /// 計算並加入一段時間段的勞保費 /// /// 投保薪資 /// 時間段起日 /// 時間段迄日 /// 退保 /// 身障補助 /// 有勞保 /// 已領老年給付 /// 超過65歲 /// 員工類型 /// 員工國籍 1=本國籍 2=外國籍 /// 本段時間勞保出席天數 public void Add(int salary, DateTime startDay, DateTime endDay, bool goOut, string disable, bool hasLIF, bool retired, bool over65, string employeeType, string nation, ref int thisMonthLaborDays) { // 無勞保,不處理 if (!hasLIF) return; // 勞保、勞退計算基準 double bsamt = GetAmont(salary); double daysRatio = 0; int days = 0; int monthEndDay = startDay.AddMonths(1).AddDays(-startDay.Day).Day; _insuranceSalary = Convert.ToInt32(bsamt); if (bsamt > 0) { // 整月 if (startDay.Day == 1 && endDay.Day == monthEndDay) { days = 30; // 若二月,且退保,要算至月底的實際天數 if (goOut && endDay.Month == 2) days = monthEndDay; } // 非整月 else { // 結束日是月底日 if (endDay.Day == monthEndDay) { if (startDay.Day == 30 || startDay.Day == 31) days = 1; else days = 30 - startDay.Day + 1; // 若二月,且退保,要算至月底的實際天數 if (goOut && endDay.Month == 2) { days -= (30 - monthEndDay); } } else // 結束日非月底日 { days = endDay.Day - startDay.Day + 1; } if (days > 30 - thisMonthLaborDays) days = 30 - thisMonthLaborDays; } _inWorkDays += days; thisMonthLaborDays += days; daysRatio = Convert.ToDouble(days) / 30d; decimal _thisNormalPersonalFee = 0; decimal _thisNormalCompanyFee = 0; decimal _thisLostJobPersonalFee = 0; decimal _thisLostJobCompanyFee = 0; if (!retired) { // 員工身份是雇主: if (employeeType == "1") { // 計算普通事故保費 _thisNormalPersonalFee = Convert.ToDecimal(Math.Round(bsamt * _normalFeeRate * daysRatio * 0.2d, 4, MidpointRounding.AwayFromZero)); _thisNormalCompanyFee = Convert.ToDecimal(Math.Round(bsamt * _normalFeeRate * daysRatio * 0.7d, 4, MidpointRounding.AwayFromZero)); // 計算就業保險保費 _thisLostJobPersonalFee = 0; _thisLostJobCompanyFee = 0; } // 員工身份是一般勞工: else { // 計算普通事故保費 _thisNormalPersonalFee = Convert.ToDecimal(Math.Round(bsamt * _normalFeeRate * daysRatio * 0.2d, 4, MidpointRounding.AwayFromZero)); _thisNormalCompanyFee = Convert.ToDecimal(Math.Round(bsamt * _normalFeeRate * daysRatio * 0.7d, 4, MidpointRounding.AwayFromZero)); // 計算就業保險保費,本國籍員工,未滿65歲才需要 if (nation == "1" && !over65) { _thisLostJobPersonalFee = Convert.ToDecimal(Math.Round(bsamt * _lostJobFeeRate * daysRatio * 0.2d, 4, MidpointRounding.AwayFromZero)); _thisLostJobCompanyFee = Convert.ToDecimal(Math.Round(bsamt * _lostJobFeeRate * daysRatio * 0.7d, 4, MidpointRounding.AwayFromZero)); } } } _normalPersonalFee += _thisNormalPersonalFee; _normalCompanyFee += _thisNormalCompanyFee; _lostJobPersonalFee += _thisLostJobPersonalFee; _lostJobCompanyFee += _thisLostJobCompanyFee; // 計算身心障礙補助 switch (disable) { case "0": // 無 break; case "1": // 輕度 _disableNormalSupport = Math.Round((_thisNormalPersonalFee) * 0.25m, MidpointRounding.AwayFromZero); _disableLostJobSupport = Math.Round((_thisLostJobPersonalFee) * 0.25m, MidpointRounding.AwayFromZero); break; case "2": // 中度 _disableNormalSupport = Math.Round((_thisNormalPersonalFee) * 0.5m, MidpointRounding.AwayFromZero); _disableLostJobSupport = Math.Round((_thisLostJobPersonalFee) * 0.5m, MidpointRounding.AwayFromZero); break; case "3": // 重度 case "4": // 極重度 _disableNormalSupport = _thisNormalPersonalFee; _disableLostJobSupport = _thisLostJobPersonalFee; break; } // 計算職災保險保費 double bljiAmt = GetBLJIAmt(salary); _injurySalary = Convert.ToInt32(bljiAmt); _injuryCompanyFee += Convert.ToDecimal(Math.Round(bljiAmt * _injuryCompanyFeeRate * daysRatio, 4, MidpointRounding.AwayFromZero)); // 計算工資墊償基金 // 員工身份是雇主: if (employeeType == "1") { _salaryReverseFund += 0; } else { _salaryReverseFund += Convert.ToDecimal(Math.Round(bsamt * daysRatio * _salaryReverseFundRate, 4, MidpointRounding.AwayFromZero)); } } } } /// /// 勞保費 /// public struct LaborInsuranceFee { /// /// 到職天數 /// public int InWorkDays; /// /// 投保薪資 /// public int InsuranceSalary; /// /// 職災投保薪資 /// public int InjurySalary; /// /// 普通事故個人保費 /// public decimal NormalPersonalFee; /// /// 普通事故公司保費 /// public decimal NormalCompanyFee; /// /// 就業保險個人保費 /// public decimal LostJobPersonalFee; /// /// 就業保險公司保費 /// public decimal LostJobCompanyFee; /// /// 職災保費 /// public decimal InjuryCompanyFee; /// /// 身障補助 /// public decimal DisableNormalSupport; /// /// 身障補助 /// public decimal DisableLostJobSupport; /// /// 工資墊償基金 /// public decimal SalaryReverseFund; public void Init() { InWorkDays = 0; InsuranceSalary = 0; InjurySalary = 0; NormalCompanyFee = 0; NormalPersonalFee = 0; LostJobCompanyFee = 0; LostJobPersonalFee = 0; InjuryCompanyFee = 0; DisableNormalSupport = 0; DisableLostJobSupport = 0; SalaryReverseFund = 0; } public void Add(LaborInsuranceFee fee) { InWorkDays += fee.InWorkDays; InsuranceSalary = fee.InsuranceSalary; InjurySalary = fee.InjurySalary; NormalCompanyFee += fee.NormalCompanyFee; NormalPersonalFee += fee.NormalPersonalFee; LostJobCompanyFee += fee.LostJobCompanyFee; LostJobPersonalFee += fee.LostJobPersonalFee; InjuryCompanyFee += fee.InjuryCompanyFee; DisableNormalSupport += fee.DisableNormalSupport; DisableLostJobSupport += fee.DisableLostJobSupport; SalaryReverseFund += fee.SalaryReverseFund; } /// /// 個人總保費 /// public int TotalPersonalFee { // { 四捨五入(普通事故) + 四捨五入(就業保險) } //- { 四捨五入(普通事故減免) + 四捨五入(就業保險減免) } get { return Convert.ToInt32(Math.Round(NormalPersonalFee, MidpointRounding.AwayFromZero)) + Convert.ToInt32(Math.Round(LostJobPersonalFee, MidpointRounding.AwayFromZero)) - Convert.ToInt32(Math.Round(DisableNormalSupport, MidpointRounding.AwayFromZero)) - Convert.ToInt32(Math.Round(DisableLostJobSupport, MidpointRounding.AwayFromZero)); } } }