chore: 首次簽入 Thinkyu ASP.NET 專案

- 加入 Visual Studio / ASP.NET .gitignore
- 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
2026-09-10 09:42:37 +08:00
commit 577060bc78
2496 changed files with 501389 additions and 0 deletions
+183
View File
@@ -0,0 +1,183 @@
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.Common;
using Wellan.Data;
using Wellan.Common;
/// <summary>
/// 計算健保費
/// </summary>
public class Bhif : LaborAndHealthFee
{
private double _healthInsuranceFeeRate;
private double _healthInsuranceAverageFamily;
private double _oldHealthInsuranceFeeRate;
public Bhif(DateTime aDate) : base(aDate)
{
_bftyp = 2;
_tableName = "BHIF";
_healthInsuranceFeeRate = 0.0455d;
_oldHealthInsuranceFeeRate = 0.0455d;
}
/// <summary>
/// 健保費率
/// </summary>
public double HealthInsuranceFeeRate
{
get
{
return _healthInsuranceFeeRate;
}
set
{
_healthInsuranceFeeRate = value;
}
}
/// <summary>
/// 健保平均眷口數
/// </summary>
public double HealthInsuranceAverageFamily
{
get
{
return _healthInsuranceAverageFamily;
}
set
{
_healthInsuranceAverageFamily = value;
}
}
public HealthInsuranceFee GetFee(int salary, int family, int family25, int family50, string disabled, bool hasHIF, string employeeType)
{
// 找出投保薪資
HealthInsuranceFee fee = new HealthInsuranceFee();
fee.Init();
// 不投健保,直接回傳
if (!hasHIF)
return fee;
// 新費率投保薪資
double bsamt = GetAmont(salary);
// 舊費率投保薪資
double oldbsamt = GetAmont(new DateTime(2010, 3, 1) ,salary);
fee.InsuranceSalary = (Int32)bsamt;
if (bsamt > 0)
{
// 計算公司保費
// 員工身份是雇主
if (employeeType == "1")
fee.CompanyFee = 0;
// 員工身份是受雇員工
else
fee.CompanyFee = Convert.ToInt32(Math.Round(bsamt * _healthInsuranceFeeRate * 0.6d * (1d + _healthInsuranceAverageFamily), MidpointRounding.AwayFromZero));
// 計算個人保費
double personalFee = 0;
double oldPersonalFee = 0;
// 員工身份是雇主
if (employeeType == "1")
{
personalFee = bsamt * _healthInsuranceFeeRate;
oldPersonalFee = oldbsamt * _oldHealthInsuranceFeeRate;
}
// 員工身份是受雇員工
else
{
personalFee = bsamt * _healthInsuranceFeeRate * 0.3d;
oldPersonalFee = oldbsamt * _oldHealthInsuranceFeeRate * 0.3d;
}
/*
99/4/1 到 101/12/31 實施差額補助
投保金額等級 所得水準 補助比率
40,100元(含)以下 約5萬1千元(含)以下 100%
42,000元至50,600元 約5萬3千元至6萬5千元 20%
53,000元(含)以上 約6萬8千元(含)以上 0%
*/
if (_baseDate.ToString("yyyyMM", WGuard1.InvariantCulture).CompareTo("201004") >= 0 &&
_baseDate.ToString("yyyyMM", WGuard1.InvariantCulture).CompareTo("201301") < 0)
{
// 以月投保薪資計算補助比率
if (bsamt <= 40100)
{
personalFee = oldPersonalFee;
}
else if (bsamt > 40100 && bsamt < 53000)
{
personalFee = personalFee - Convert.ToInt32(Math.Round((personalFee - oldPersonalFee) * 0.2d, MidpointRounding.AwayFromZero));
}
}
int noDiscountFee = Convert.ToInt32(Math.Round(personalFee, MidpointRounding.AwayFromZero));
int discount25Fee = Convert.ToInt32(Math.Truncate(Math.Round(personalFee, MidpointRounding.AwayFromZero) * 0.75d));
int discount50Fee = Convert.ToInt32(Math.Truncate(Math.Round(personalFee, MidpointRounding.AwayFromZero) * 0.5d));
int remainFamily = 3;
switch (disabled)
{
case "0": // 無
fee.PersonalFee = noDiscountFee;
break;
case "1": // 輕度
fee.PersonalFee = discount25Fee;
break;
case "2": // 中度
fee.PersonalFee = discount50Fee;
break;
case "3": // 重度
fee.PersonalFee = 0;
break;
}
// 加上一般眷口
fee.PersonalFee += noDiscountFee * (family > remainFamily ? (remainFamily > 0 ? remainFamily : 0) : family);
remainFamily -= family;
// 加上減免25%眷口
fee.PersonalFee += (discount25Fee) * (family25 > remainFamily ? (remainFamily > 0 ? remainFamily : 0) : family25);
remainFamily -= family25;
// 加上減免50%眷口
fee.PersonalFee += (discount50Fee) * (family50 > remainFamily ? (remainFamily > 0 ? remainFamily : 0) : family50);
}
return fee;
}
}
public struct HealthInsuranceFee
{
public int InsuranceSalary;
public int PersonalFee;
public int CompanyFee;
public void Init()
{
InsuranceSalary = 0;
PersonalFee = 0;
CompanyFee = 0;
}
public void Assign(HealthInsuranceFee fee)
{
InsuranceSalary = fee.InsuranceSalary;
PersonalFee = fee.PersonalFee;
CompanyFee = fee.CompanyFee;
}
}
+457
View File
@@ -0,0 +1,457 @@
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;
/// <summary>
/// 計算勞保費
/// </summary>
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<DateTime, List<LHFClass>> _bljiAmtData;
public Blif(DateTime aDate) : base(aDate)
{
_bftyp = 1;
_tableName = "BLIF";
}
/// <summary>
/// 普通事故費率
/// </summary>
public double NormalFeeRate
{
get
{
return _normalFeeRate;
}
set
{
_normalFeeRate = value;
}
}
/// <summary>
/// 就業保險費率
/// </summary>
public double LostJobFeeRate
{
get
{
return _lostJobFeeRate;
}
set
{
_lostJobFeeRate = value;
}
}
/// <summary>
/// 工資墊償基金費率
/// </summary>
public double SalaryReverseFundRate
{
get
{
return _salaryReverseFundRate;
}
set
{
_salaryReverseFundRate = value;
}
}
/// <summary>
/// 職災保險費率
/// </summary>
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;
}
/// <summary>
/// 取得職災級距表
/// </summary>
/// <param name="aDate">日期</param>
private void GetBLJIData(DateTime aDate)
{
if (this._bljiAmtData == null)
_bljiAmtData = new Dictionary<DateTime, List<LHFClass>>();
if (!_bljiAmtData.ContainsKey(aDate))
{
List<LHFClass> _newAmtDataItem = new List<LHFClass>();
// 取得適用級距表版本
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);
}
}
/// <summary>
/// 取得職災保險投保薪資
/// </summary>
/// <param name="aDate">日期</param>
/// <param name="salary">薪資</param>
/// <returns></returns>
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;
}
/// <summary>
/// 取得職災保險投保薪資
/// </summary>
/// <param name="salary">薪資</param>
/// <returns></returns>
protected double GetBLJIAmt(int salary)
{
return GetBLJIAmt(_baseDate, salary);
}
/// <summary>
/// 計算並加入一段時間段的勞保費
/// </summary>
/// <param name="salary">投保薪資</param>
/// <param name="startDay">時間段起日</param>
/// <param name="endDay">時間段迄日</param>
/// <param name="goOut">退保</param>
/// <param name="disable">身障補助</param>
/// <param name="hasLIF">有勞保</param>
/// <param name="retired">已領老年給付</param>
/// <param name="over65">超過65歲</param>
/// <param name="employeeType">員工類型</param>
/// <param name="nation">員工國籍 1=本國籍 2=外國籍</param>
/// <param name="thisMonthLaborDays">本段時間勞保出席天數</param>
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));
}
}
}
}
/// <summary>
/// 勞保費
/// </summary>
public struct LaborInsuranceFee
{
/// <summary>
/// 到職天數
/// </summary>
public int InWorkDays;
/// <summary>
/// 投保薪資
/// </summary>
public int InsuranceSalary;
/// <summary>
/// 職災投保薪資
/// </summary>
public int InjurySalary;
/// <summary>
/// 普通事故個人保費
/// </summary>
public decimal NormalPersonalFee;
/// <summary>
/// 普通事故公司保費
/// </summary>
public decimal NormalCompanyFee;
/// <summary>
/// 就業保險個人保費
/// </summary>
public decimal LostJobPersonalFee;
/// <summary>
/// 就業保險公司保費
/// </summary>
public decimal LostJobCompanyFee;
/// <summary>
/// 職災保費
/// </summary>
public decimal InjuryCompanyFee;
/// <summary>
/// 身障補助
/// </summary>
public decimal DisableNormalSupport;
/// <summary>
/// 身障補助
/// </summary>
public decimal DisableLostJobSupport;
/// <summary>
/// 工資墊償基金
/// </summary>
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;
}
/// <summary>
/// 個人總保費
/// </summary>
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));
}
}
}
+155
View File
@@ -0,0 +1,155 @@
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.Common;
using Wellan.Data;
using Wellan.Common;
/// <summary>
/// 計算勞退金
/// </summary>
public class Blra : LaborAndHealthFee
{
private int _annuitySalary;
private double _companyFee;
private double _personalFee;
private int _inworkdays;
public Blra(DateTime aDate)
: base(aDate)
{
_bftyp = 3;
_tableName = "BLRA";
}
public LaborRetireAnnuity GetFee()
{
LaborRetireAnnuity fee = new LaborRetireAnnuity();
fee.Init();
fee.CompanyFee = Convert.ToInt32(Math.Round(_companyFee, MidpointRounding.AwayFromZero));
fee.PersonalFee = Convert.ToInt32(Math.Round(_personalFee, MidpointRounding.AwayFromZero));
fee.AnnuitySalary = _annuitySalary;
return fee;
}
public void Clear()
{
_annuitySalary = 0;
_companyFee = 0;
_personalFee = 0;
_inworkdays = 0;
}
/// <summary>
/// 計算勞退提撥,並加入 Blra 的執行個體中
/// </summary>
/// <param name="salary">月薪</param>
/// <param name="startDay">本月在職起始日</param>
/// <param name="endDay">本月在職結束日</param>
/// <param name="personalRate">個人提繳率</param>
/// <param name="employeeType">員工類別 1=雇主 2=員工</param>
/// <param name="thisMonthDays">本月到職天數</param>
/// <param name="nation">員工國籍 1=本國籍 2=外國籍</param>
public void Add(int salary, DateTime startDay, DateTime endDay, int personalRate, string employeeType, int thisMonthDays, string nation)
{
// 外國籍員工沒有勞退提撥
if (nation == "2")
return;
double bsamt = GetAmont(salary);
double daysRatio = 0;
int days = 0;
int monthEndDay = WGuard1.GetMonthEnd(startDay, 0).Day;
_annuitySalary = Convert.ToInt32(bsamt);
if (bsamt > 0)
{
// 月初日到月底日
if (startDay.Day == 1 && endDay.Day == monthEndDay)
{
days = 30;
}
else
{
// 結束日是月底日
if (endDay.Day == monthEndDay)
{
if (startDay.Day == 30 || startDay.Day == 31)
days = 1;
else
days = 30 - startDay.Day + 1;
}
else
// 結束日非月底日
{
days = endDay.Day - startDay.Day + 1;
}
if (days > 30)
days = 30;
}
/*
// 月初日到月底日,以 30 天計算
if (startDay.Day == 1 && endDay.Day == monthEndDay)
{
days = 30;
}
else
{
// 結束日是月底日,用 30 去減
//if (endDay.Day == monthEndDay)
// days = 30 - startDay.Day + 1;
// 結束日非月底日,用實際結束日去減
//else
days = endDay.Day - startDay.Day + 1;
// 調整天數,最多 30 天
if (days > 30)
days = 30;
}
*/
// 若本月累計天數 > 30 則減去多出的天數
if (_inworkdays + days > 30)
days = 30 - _inworkdays;
_inworkdays += days;
daysRatio = Convert.ToDouble(days) / 30d;
// 計算公司提撥
if (employeeType == "1") // 員工身份是雇主
_companyFee += 0;
else
_companyFee += Math.Round(bsamt * 0.06 * daysRatio, 4, MidpointRounding.AwayFromZero);
// 計算個人提撥
_personalFee += Math.Round(bsamt * ((double)personalRate / 100) * daysRatio, 4, MidpointRounding.AwayFromZero);
}
}
}
public struct LaborRetireAnnuity
{
public int CompanyFee;
public int PersonalFee;
public int AnnuitySalary;
public void Init()
{
AnnuitySalary = 0;
CompanyFee = 0;
PersonalFee = 0;
}
public void Add(LaborRetireAnnuity fee)
{
AnnuitySalary = fee.AnnuitySalary;
CompanyFee += fee.CompanyFee;
PersonalFee += fee.PersonalFee;
}
}
+931
View File
@@ -0,0 +1,931 @@
using System;
using System.Data;
using System.Configuration;
using System.Data.Common;
using Wellan.Common;
using Wellan.Data;
/// <summary>
/// 計算加班費
/// 1. 取出這個年月的這個人員的加班紀錄
/// 2. 若要累積補休(11),就累加進累積補休
/// 3. 若要請領加班費(12),就看那天是不是假日
/// 4. 是假日:假日加班費率 * 8 * 時薪
/// 5. 不是假日:區分出 前二時數 與 後二時數
/// 6. 前二加班:前二加班費率 * 前二時數 * 時薪
/// 7. 後二加班:後二加班費率 * 後二時數 * 時薪
/// 8. 累加加班費、前二時數、後二時數、假日時數
/// </summary>
public class ExtraWork
{
private BhrdDAC bhrd = new BhrdDAC();
private static Calculate calc = new Calculate();
/// <summary>
/// 累積補休時數
/// </summary>
public int RelaxationAllowance = 0;
/// <summary>
/// 前二加班時數
/// </summary>
public int RPTC1 = 0;
private double _RPTA1 = 0d;
/// <summary>
/// 前二加班費
/// </summary>
public int RPTA1
{
get
{
return (Int32)Math.Round(_RPTA1, MidpointRounding.AwayFromZero);
}
set
{
_RPTA1 = value;
}
}
/// <summary>
/// 後二加班時數
/// </summary>
public int RPTC2 = 0;
private double _RPTA2 = 0d;
/// <summary>
/// 後二加班費
/// </summary>
public int RPTA2
{
get
{
return (Int32)Math.Round(_RPTA2, MidpointRounding.AwayFromZero);
}
set
{
_RPTA2 = value;
}
}
/// <summary>
/// 假日加班時數
/// </summary>
public int RPTC3 = 0;
private double _RPTA3 = 0d;
/// <summary>
/// 假日加班費
/// </summary>
public int RPTA3
{
get
{
return (Int32)Math.Round(_RPTA3, MidpointRounding.AwayFromZero);
}
set
{
_RPTA3 = value;
}
}
/// <summary>
/// 休息日加班超過 8 小時時數
/// </summary>
public int RPTC4 = 0;
private double _RPTA4 = 0d;
/// <summary>
/// 休息日加班超過 8 小時加班費
/// </summary>
public int RPTA4
{
get
{
return (Int32)Math.Round(_RPTA4, MidpointRounding.AwayFromZero);
}
set
{
_RPTA4 = value;
}
}
/// <summary>
/// 例假日加班超過 8 小時時數
/// </summary>
public int RPTC5 = 0;
private double _RPTA5 = 0d;
/// <summary>
/// 例假日加班超過 8 小時加班費
/// </summary>
public int RPTA5
{
get
{
return (Int32)Math.Round(_RPTA5, MidpointRounding.AwayFromZero);
}
set
{
_RPTA5 = value;
}
}
public RASNRecord RasnRecord;
public ExtraWork()
{
}
public void Clear()
{
RelaxationAllowance = 0;
RPTC1 = 0;
RPTC2 = 0;
RPTC3 = 0;
RPTC4 = 0;
RPTC5 = 0;
RPTA1 = 0;
RPTA2 = 0;
RPTA3 = 0;
RPTA4 = 0;
RPTA5 = 0;
}
/// <summary>
/// 計算加班費
/// </summary>
/// <param name="bpsrm">月薪</param>
/// <param name="bpp02">伙食津貼</param>
/// <param name="hours">時數</param>
/// <param name="ratio">比例</param>
/// <param name="bpovr">計算公式</param>
/// <param name="bpott">加班費計算方式</param>
public static int CalculateOverTimeInt(int bpsrm, int bpp02, int hours, double ratio, string bpovr, string bpott)
{
return (Int32)Math.Round(CalculateOverTime(bpsrm, bpp02, hours, ratio, 1D, bpovr), MidpointRounding.AwayFromZero);
}
/// <summary>
/// 計算加班費
/// </summary>
/// <param name="bpsrm">月薪</param>
/// <param name="bpp02">伙食津貼</param>
/// <param name="hours">時數</param>
/// <param name="overtimeRatio">加班費比例</param>
/// <param name="leaveRatio">請假扣款比例</param>
/// <param name="bpovr">計算公式</param>
/// <param name="bpott">加班費計算方式</param>
/// <returns></returns>
public static double CalculateOverTime(int bpsrm, int bpp02, int hours, double overtimeRatio, double leaveRatio, string bpovr)
{
return calc.CalcOverTime(bpsrm, bpp02, hours, overtimeRatio, leaveRatio, bpovr);
}
/// <summary>
/// 區分加班時數(支援累積模式)
/// </summary>
/// <param name="加班類型">加班類型</param>
/// <param name="本筆分鐘數">本次加班分鐘數</param>
/// <param name="含本筆累計分鐘數">處理前累計時數(用於多張加班單累積計算)</param>
/// <param name="tc1">加班分鐘數(1.34)</param>
/// <param name="tc2">加班分鐘數(1.67)</param>
/// <param name="tc3">加班分鐘數(1.00)</param>
/// <param name="tc4">加班分鐘數(2.67)</param>
/// <param name="tc5">加班分鐘數(2.00)</param>
public void SplitOverTime(string , int , int ,
out int tc1, out int tc2, out int tc3, out int tc4, out int tc5)
{
tc1 = 0;
tc2 = 0;
tc3 = 0;
tc4 = 0;
tc5 = 0;
int minBefore = - ;
int minAfter = ;
switch ()
{
case RPAR_TYPE.T11_非休息日累積補休時數:
case RPAR_TYPE.T12_非休息日請領加班費:
(, minBefore, minAfter, out tc1, out tc2);
break;
case RPAR_TYPE.T13_休息日累積補休時數:
case RPAR_TYPE.T14_休息日請領加班費:
(, minBefore, minAfter, out tc1, out tc2, out tc4);
break;
case RPAR_TYPE.T15_國定假日累積補休時數:
case RPAR_TYPE.T16_國定假日請領加班費:
(, minBefore, minAfter, out tc1, out tc2, out tc3);
break;
case RPAR_TYPE.T17_例假日累積補休時數:
case RPAR_TYPE.T18_例假日請領加班費:
(, minBefore, minAfter, out tc3, out tc5);
break;
}
}
/// <summary>
/// 分配非休息日加班時數
/// 規則:前 120 分鐘為 tc1(1.34),超過部分為 tc2(1.67)
/// </summary>
private void (int , int , int ,
out int tc1, out int tc2)
{
const int = 120;
tc1 = 0;
tc2 = 0;
if ( <= )
{
// 未超過門檻:全部算入 tc1
tc1 = ;
}
else if ( >= )
{
// 之前已超過門檻:全部算入 tc2
tc2 = ;
}
else
{
// 本筆跨越門檻:分配至 tc1 和 tc2
tc1 = - ;
tc2 = - tc1;
}
}
/// <summary>
/// 分配休息日加班時數
/// 規則:0-120 分鐘為 tc1(1.34)120-480 分鐘為 tc2(1.67),超過 480 分鐘為 tc4(2.67)
/// </summary>
private void (int , int , int ,
out int tc1, out int tc2, out int tc4)
{
const int = 120;
const int = 480;
tc1 = 0;
tc2 = 0;
tc4 = 0;
if ( <= )
{
// 未超過第一門檻
tc1 = ;
}
else if ( <= )
{
// 在第一和第二門檻之間
if ( >= )
{
tc2 = ;
}
else
{
tc1 = - ;
tc2 = - tc1;
}
}
else
{
// 超過第二門檻
if ( >= )
{
tc4 = ;
}
else if ( >= )
{
tc2 = - ;
tc4 = - tc2;
}
else
{
tc1 = - ;
tc2 = - ;
tc4 = - tc1 - tc2;
}
}
}
/// <summary>
/// 分配國定假日加班時數
/// 規則:0-480 分鐘為 tc3(1.00)480-600 分鐘為 tc1(1.34),超過 600 分鐘為 tc2(1.67)
/// </summary>
private void (int , int , int ,
out int tc1, out int tc2, out int tc3)
{
const int = 480;
const int = 600;
tc1 = 0;
tc2 = 0;
tc3 = 0;
if ( <= )
{
// 未超過第一門檻:全部算入 tc3
tc3 = ;
}
else if ( <= )
{
// 在第一和第二門檻之間
if ( >= )
{
tc1 = ;
}
else
{
tc3 = - ;
tc1 = - tc3;
}
}
else
{
// 超過第二門檻
if ( >= )
{
tc2 = ;
}
else if ( >= )
{
tc1 = - ;
tc2 = - tc1;
}
else
{
tc3 = - ;
tc1 = - ;
tc2 = - tc3 - tc1;
}
}
}
/// <summary>
/// 分配例假日加班時數
/// 規則:0-480 分鐘為 tc3(1.00),超過 480 分鐘為 tc5(2.00)
/// </summary>
private void (int , int , int ,
out int tc3, out int tc5)
{
const int = 480;
tc3 = 0;
tc5 = 0;
if ( <= )
{
// 未超過門檻:全部算入 tc3
tc3 = ;
}
else if ( >= )
{
// 之前已超過門檻:全部算入 tc5
tc5 = ;
}
else
{
// 本筆跨越門檻:分配至 tc3 和 tc5
tc3 = - ;
tc5 = - tc3;
}
}
/// <summary>
/// 增加加班時數
/// </summary>
/// <param name="rptyp">類別</param>
/// <param name="rprdt">加班日期</param>
/// <param name="rptct">當日加班時數(分鐘)</param>
/// <param name="bpsrm">月薪</param>
/// <param name="bpp02">伙食津貼</param>
/// <param name="bpbft">前二比例</param>
/// <param name="bpaft">後二比例</param>
/// <param name="bphol">假日比例</param>
/// <param name="formula">計算公式</param>
/// <param name="bpott">加班時數計算方式</param>
/// <param name="rptc1">前段加班時數(分鐘)</param>
/// <param name="rptc2">後段加班時數(分鐘)</param>
/// <param name="rptc3">假日加班時數(分鐘)</param>
public ExtraWorkData Add(string rptyp, DateTime rprdt, int rptct, int bpsrm, int bpp02,
double bpbft, double bpaft, double bphol, string formula, string bpott,
int rptc1, int rptc2, int rptc3, int rptc4, int rptc5
/*string 上班時間, string 下班時間*/)
{
ExtraWorkData result = new ExtraWorkData();
switch (rptyp)
{
case RPAR_TYPE.T11_非休息日累積補休時數:
case RPAR_TYPE.T13_休息日累積補休時數:
case RPAR_TYPE.T15_國定假日累積補休時數:
case RPAR_TYPE.T17_例假日累積補休時數:
result.RelaxationAllowance = rptct;
RelaxationAllowance += rptct;
break;
//if (rprdt < new DateTime(2018, 3, 1))
//{
// decimal calcMin = Math.Ceiling((decimal)rptct / 240m) * 240m;
// result.RelaxationAllowance = (int)calcMin;
// RelaxationAllowance += (int)calcMin;
//}
//else
//{
// result.RelaxationAllowance = rptct;
// RelaxationAllowance += rptct;
//}
//break;
case RPAR_TYPE.T12_非休息日請領加班費:
case RPAR_TYPE.T14_休息日請領加班費:
case RPAR_TYPE.T16_國定假日請領加班費:
case RPAR_TYPE.T18_例假日請領加班費:
// 1.34時數
result.RPTC1 = rptc1;
result.RPTA1 = CalculateOverTime(bpsrm, bpp02, rptc1, bpbft, 1D, formula);
RPTC1 += rptc1;
_RPTA1 += result.RPTA1;
// 1.67時數
result.RPTC2 = rptc2;
result.RPTA2 = CalculateOverTime(bpsrm, bpp02, rptc2, bpaft, 1D, formula);
RPTC2 += rptc2;
_RPTA2 += result.RPTA2;
// 1.00時數
result.RPTC3 = rptc3;
result.RPTA3 = CalculateOverTime(bpsrm, bpp02, rptc3, bphol, 1D, formula);
RPTC3 += rptc3;
_RPTA3 += result.RPTA3;
// 2.67時數
result.RPTC4 = rptc4;
result.RPTA4 = CalculateOverTime(bpsrm, bpp02, rptc4, bpaft + 1D, 1D, formula);
RPTC4 += rptc4;
_RPTA4 += result.RPTA4;
// 2.00時數
result.RPTC5 = rptc5;
result.RPTA5 = CalculateOverTime(bpsrm, bpp02, rptc5, bphol + 1D, 1D, formula);
RPTC5 += rptc5;
_RPTA5 += result.RPTA5;
break;
}
return result;
}
public void Add(ROWKRecord rowkRecord)
{
this.RPTC1 += rowkRecord.ROT01;
this.RPTC2 += rowkRecord.ROT02;
this.RPTC3 += rowkRecord.ROT03;
this.RPTC4 += rowkRecord.ROT05;
this.RPTC5 += rowkRecord.ROT06;
this.RPTA1 += rowkRecord.ROA01;
this.RPTA2 += rowkRecord.ROA02;
this.RPTA3 += rowkRecord.ROA03;
this.RPTA4 += rowkRecord.ROA05;
this.RPTA5 += rowkRecord.ROA06;
this.RelaxationAllowance += rowkRecord.ROT04;
}
}
public class ExtraWorkData
{
/// <summary>
/// 1.34 加班時數
/// </summary>
public int RPTC1 = 0;
/// <summary>
/// 1.67 加班時數
/// </summary>
public int RPTC2 = 0;
/// <summary>
/// 1.00 加班時數
/// </summary>
public int RPTC3 = 0;
/// <summary>
/// 2.67 加班時數
/// </summary>
public int RPTC4 = 0;
/// <summary>
/// 2.00 加班時數
/// </summary>
public int RPTC5 = 0;
/// <summary>
/// 累積補休
/// </summary>
public int RelaxationAllowance = 0;
/// <summary>
/// 1.34 加班費
/// </summary>
public Double RPTA1 = 0;
/// <summary>
/// 1.67 加班費
/// </summary>
public Double RPTA2 = 0;
/// <summary>
/// 1.00 加班費
/// </summary>
public Double RPTA3 = 0;
/// <summary>
/// 2.67 加班費
/// </summary>
public Double RPTA4 = 0;
/// <summary>
/// 2.00 加班費
/// </summary>
public Double RPTA5 = 0;
}
/*
2. 計算缺勤扣款
1. 取出這個年月的這個人員的請假紀錄
2. 區分出扣薪假與不扣薪假
3. 扣薪假:事假:時數 * 時薪
病假:(時數 * 時薪) / 2
4. 累加各假別時數、扣薪金額
*/
public class Absent
{
private Calculate calc = new Calculate();
public Absent()
{
}
/// <summary>
/// 月薪
/// </summary>
public int bpsrm;
/// <summary>
/// 伙食津貼
/// </summary>
public int bpp02;
/// <summary>
/// 計算公式
/// </summary>
public string Formula;
/// <summary>
/// 補休請假時數
/// </summary>
public int SST05 = 0;
/// <summary>
/// 特休時數
/// </summary>
public int SST06 = 0;
/// <summary>
/// 事假時數
/// </summary>
public int SST07 = 0;
/// <summary>
/// 病假時數
/// </summary>
public int SST08 = 0;
/// <summary>
/// 喪假時數,不影響全勤
/// </summary>
public int SST09 = 0;
/// <summary>
/// 產假時數
/// </summary>
public int SST10 = 0;
/// <summary>
/// 婚假時數,不影響全勤
/// </summary>
public int SST11 = 0;
/// <summary>
/// 陪產假時數
/// </summary>
public int SST12 = 0;
/// <summary>
/// 公假時數,不影響全勤
/// </summary>
public int SST13 = 0;
/// <summary>
/// 公傷假時數,不影響全勤
/// </summary>
public int SST14 = 0;
/// <summary>
/// 生理假時數,不影響全勤
/// </summary>
public int SST15 = 0;
/// <summary>
/// 家庭照顧假時數,不影響全勤
/// </summary>
public int SST16 = 0;
/// <summary>
/// 育嬰假時數
/// </summary>
public int SST17 = 0;
/// <summary>
/// 原民祭儀假
/// </summary>
public int SST19 = 0;
/// <summary>
/// 產檢假時數
/// </summary>
public int SST20 = 0;
/// <summary>
/// 病假扣款
/// </summary>
public int SSS01 = 0;
/// <summary>
/// 事假扣款
/// </summary>
public int SSS02 = 0;
/// <summary>
/// 其他假別(一)時數,不影響全勤
/// </summary>
public int SST23 = 0;
/// <summary>
/// 無薪扣款
/// </summary>
public int SSS09 = 0;
public void Clear()
{
SST05 = 0;
SST06 = 0;
SST07 = 0;
SST08 = 0;
SST09 = 0;
SST10 = 0;
SST11 = 0;
SST12 = 0;
SST13 = 0;
SST14 = 0;
SST15 = 0;
SST16 = 0;
SST17 = 0;
SST19 = 0;
SST20 = 0;
SST23 = 0;
SSS01 = 0;
SSS02 = 0;
SSS09 = 0;
}
/// <summary>
/// 以假別與總時數計算請假扣款與區分時數
/// </summary>
/// <param name="rptyp">假別</param>
/// <param name="rptct">時數</param>
/// <returns>請假扣款</returns>
public int Add(string rptyp, int rptct)
{
int rpftr = 0;
switch (rptyp)
{
case RPAR_TYPE.T00_補休: //補休時數
SST05 += rptct;
break;
case RPAR_TYPE.T01_特休: //特休時數
SST06 += rptct;
break;
case RPAR_TYPE.T02_事假: //事假時數
SST07 += rptct;
rpftr = Convert.ToInt32(calc.CalcOverTime(bpsrm, bpp02, rptct, 0D, 1D, Formula));
SSS02 += rpftr;
break;
case RPAR_TYPE.T03_病假: //病假時數
SST08 += rptct;
rpftr = Convert.ToInt32(calc.CalcOverTime(bpsrm, bpp02, rptct, 0D, 0.5D, Formula));
SSS01 += rpftr;
break;
case RPAR_TYPE.T04_喪假: //喪假時數
SST09 += rptct;
break;
case RPAR_TYPE.T05_產假: //產假時數
SST10 += rptct;
break;
case RPAR_TYPE.T06_婚假: //婚假時數
SST11 += rptct;
break;
case RPAR_TYPE.T07_陪產假: //陪產假時數
SST12 += rptct;
break;
case RPAR_TYPE.T08_公假: //公假時數
SST13 += rptct;
break;
case RPAR_TYPE.T09_公傷假: //公傷假時數
SST14 += rptct;
break;
case RPAR_TYPE.T0A_生理假: //生理假時數
SST15 += rptct;
rpftr = Convert.ToInt32(calc.CalcOverTime(bpsrm, bpp02, rptct, 0D, 0.5D, Formula));
SSS01 += rpftr;
break;
case RPAR_TYPE.T0B_家庭照顧假: //家庭照顧假時數
SST16 += rptct;
rpftr = Convert.ToInt32(calc.CalcOverTime(bpsrm, bpp02, rptct, 0D, 1D, Formula));
SSS02 += rpftr;
break;
case RPAR_TYPE.T0C_育嬰假: //育嬰假時數
SST17 += rptct;
break;
case RPAR_TYPE.T0D_原民祭儀假: //原民祭儀假
SST19 += rptct;
break;
case RPAR_TYPE.T0E_產檢假: //產檢假時數
SST20 += rptct;
break;
case RPAR_TYPE.T0G_無薪假: //無薪假時數
case RPAR_TYPE.T0F_防疫照顧假:
SST23 += rptct;
rpftr = Convert.ToInt32(calc.CalcOverTime(bpsrm, bpp02, rptct, 0D, 1D, Formula));
SSS09 += rpftr;
break;
case RPAR_TYPE.T0H_防疫隔離假:
SST23 += rptct;
break;
}
return rpftr;
}
public int Add(RPARRecord rparRecord, DateTime calcStartDay, DateTime calcEndDay, bool is進整小時)
{
DateTime = rparRecord.RPRDT;
DateTime = rparRecord.RPEDT;
string = rparRecord.RPRTM;
string = rparRecord.RPETM;
TimeCalc timeCalc = new TimeCalc();
if (.Length > 0 && .Length > 0)
{
return Add(rparRecord.RPNUM, rparRecord.RPTYP, , , , , calcStartDay, calcEndDay, is進整小時);
}
else
return Add(rparRecord.RPTYP, rparRecord.RPTCT);
}
public int Add(string RPNUM, string RPTYP, DateTime , DateTime , string , string , DateTime calcStartDay, DateTime calcEndDay, bool is進整小時)
{
TimeCalc timeCalc = new TimeCalc();
if ( < calcStartDay)
{
= calcStartDay;
}
if ( > calcEndDay)
{
= calcEndDay;
}
if (string.IsNullOrEmpty())
{
= timeCalc.;
}
if (string.IsNullOrEmpty())
{
= timeCalc.;
}
if ( != )
{
var rpftr = 0;
var dt = ;
while (dt <= )
{
rpftr += Add(RPTYP, timeCalc.(RPNUM, dt, , , , , RPTYP, is進整小時));
dt = dt.AddDays(1);
}
return rpftr;
}
else
{
return Add(RPTYP, timeCalc.(RPNUM, , , , , RPTYP, is進整小時));
}
}
/// <summary>
/// 是否全勤
/// </summary>
public bool AllPresent
{
get
{
return (SST07 == 0) && (SST08 == 0) && (SST10 == 0) && (SST12 == 0);
}
}
}
/// <summary>
/// 計算其他費用
/// </summary>
public class OtherFee
{
public OtherFee()
{
}
/// <summary>
/// 短程出差差旅費
/// </summary>
public int ShortTrip = 0;
/// <summary>
/// 長途出差差旅費
/// </summary>
public int LongTrip = 0;
/// <summary>
/// 電話費補助
/// </summary>
public int TelephoneFee = 0;
/// <summary>
/// 油料費補助公里數
/// </summary>
public int FuelKm = 0;
/// <summary>
/// 油料費補助金額
/// </summary>
public int FuelFee = 0;
public void Clear()
{
ShortTrip = 0;
LongTrip = 0;
TelephoneFee = 0;
FuelKm = 0;
FuelFee = 0;
}
public void Add(string rptyp, int rptct, int rpftr)
{
switch (rptyp)
{
case RPAR_TYPE.T21_電話費: // 電話費
TelephoneFee += rpftr;
break;
case RPAR_TYPE.T22_油料費: // 油料費
FuelKm += rptct;
FuelFee += Convert.ToInt32(Math.Round((double)rptct * 2.5d, MidpointRounding.AwayFromZero));
break;
case RPAR_TYPE.T31_短程出差: // 短程差旅
case RPAR_TYPE.T33_公出: // 公出
case RPAR_TYPE.T34_公假: // 公假
ShortTrip += rpftr;
break;
case RPAR_TYPE.T32_長程出差: // 長途差旅
LongTrip += rpftr;
break;
}
}
public void Add(RPARRecord rparRecord)
{
Add(rparRecord.RPTYP, rparRecord.RPTCT, rparRecord.RPFTR);
}
}
/// <summary>
/// 計算公式
/// </summary>
public class Calculate : Wellan.Data.WDAC
{
private DbCommand cmdCalc;
public Calculate()
{
cmdCalc = Query.NewCommand();
cmdCalc.Parameters.Add(Query.NewParameter("月薪", DbType.Double));
cmdCalc.Parameters.Add(Query.NewParameter("本薪", DbType.Double));
cmdCalc.Parameters.Add(Query.NewParameter("伙食費", DbType.Double));
cmdCalc.Parameters.Add(Query.NewParameter("時數", DbType.Double));
cmdCalc.Parameters.Add(Query.NewParameter("加班費比例", DbType.Double));
cmdCalc.Parameters.Add(Query.NewParameter("請假扣款比例", DbType.Double));
}
/// <summary>
/// 計算加班費與請假扣款
/// </summary>
/// <param name="bpsrm">月薪</param>
/// <param name="bpp02">伙食津貼</param>
/// <param name="hours">時數(分鐘)</param>
/// <param name="overtimeRatio">加班費比例</param>
/// <param name="leaveRatio">請假扣款比例</param>
/// <param name="formula">計算公式</param>
/// <returns></returns>
public Double CalcOverTime(int bpsrm, int bpp02, int hours, double overtimeRatio, double leaveRatio, string formula)
{
cmdCalc.CommandText = "SELECT ROUND(" + formula + ", 0)";
cmdCalc.Parameters["月薪"].Value = Convert.ToDouble(bpsrm);
cmdCalc.Parameters["本薪"].Value = Convert.ToDouble(bpsrm - bpp02);
cmdCalc.Parameters["伙食費"].Value = Convert.ToDouble(bpp02);
cmdCalc.Parameters["時數"].Value = Convert.ToDouble(hours) / 60d;
cmdCalc.Parameters["加班費比例"].Value = Convert.ToDouble(overtimeRatio);
cmdCalc.Parameters["請假扣款比例"].Value = Convert.ToDouble(leaveRatio);
int result;
if (ExecuteScalar(cmdCalc, out result))
return result;
else
return 0d;
}
}
+127
View File
@@ -0,0 +1,127 @@
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.Common;
using Wellan.Data;
using Wellan.Common;
using System.Collections.Generic;
/// <summary>
/// 計算勞健保費基礎類別
/// </summary>
public class LaborAndHealthFee
{
protected WQuery _query;
protected DateTime _baseDate;
protected Dictionary<DateTime, List<LHFClass>> _amtData;
protected int _bftyp;
protected string _tableName;
/// <param name="aDate">計算日期</param>
public LaborAndHealthFee(DateTime baseDate)
{
WConnectionString.ConnectionConfigFile = WConfig.GetConnectionConfig();
WConnectionString.ConnectionConfigName = WConfig.GetConnectionConfigName();
_query = new WQuery(WConnectionString.GetConnectionType(), WConnectionString.GetConnectionString());
_baseDate = baseDate;
}
/// <summary>
/// 取得特定日期的級距表
/// </summary>
/// <param name="aDate"></param>
protected void GetData(DateTime aDate)
{
if (_amtData == null)
_amtData = new Dictionary<DateTime,List<LHFClass>>();
if (!_amtData.ContainsKey(aDate))
{
List<LHFClass> _newAmtDataItem = new List<LHFClass>();
// 取得適用級距表版本
DataTable _verData = _query.Select(String.Format("SELECT * FROM BFDT WHERE BFTYP={0} ORDER BY BFVER", _bftyp));
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 {1} WHERE BSVER={0} ORDER BY BSLVL", version, _tableName));
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"])));
}
_amtData.Add(aDate, _newAmtDataItem);
}
}
// 取得目前級距表
protected void GetData()
{
GetData(_baseDate);
}
/// <summary>
/// 以特定日期適用的級距表,取得特定日期適用的投保薪資
/// </summary>
/// <param name="aDate"></param>
/// <param name="salary"></param>
/// <returns></returns>
protected double GetAmont(DateTime aDate, int salary)
{
GetData(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;
}
/// <summary>
/// 以目前級距表,取得投保薪資
/// </summary>
/// <param name="salary"></param>
/// <returns></returns>
protected double GetAmont(int salary)
{
return GetAmont(_baseDate, salary);
}
protected struct LHFClass
{
public int Low;
public int High;
public int Amt;
public LHFClass(int aLow, int aHigh, int aAmt)
{
Low = aLow;
High = aHigh;
Amt = aAmt;
}
}
}
+555
View File
@@ -0,0 +1,555 @@
using System;
using System.Linq;
using System.Xml.Linq;
using Wellan.Common;
/// <summary>
/// 計算時數的類別
/// </summary>
public class TimeCalc
{
public string ;
public string ;
public string ;
public string ;
public int ;
public int ;
public bool ;
private BhrdDAC bhrdDao = new BhrdDAC(WGuard1.Query);
private RtmeDAC rtmeDao = new RtmeDAC(WGuard1.Query);
private BpsnDAC bpsnDao = new BpsnDAC(WGuard1.Query);
private BpaaDAC bpaaDao = new BpaaDAC(WGuard1.Query);
private BtmeDAC btmeDao = new BtmeDAC(WGuard1.Query);
public TimeCalc()
{
}
/// <summary>
/// 計算時數之前取得各個時間點
/// </summary>
/// <param name="員工編號"></param>
/// <param name="日期"></param>
public void Init(string , DateTime )
{
= WGuard1.WSetR("UNRPARTIME", 1);
= WGuard1.WSetR("UNRPARTIME", 2);
= WGuard1.WSetR("UNRPARTIME", 3);
= WGuard1.WSetR("UNRPARTIME", 4);
= WGuard1.WSetR("彈性上班時間", 1) == "Y";
// 取員工班表
var btmeItem = rtmeDao.SelectBtmeDay(, );
if (btmeItem != null && !String.IsNullOrEmpty(btmeItem.BTSTM) && !String.IsNullOrEmpty(btmeItem.BTETM)
&& !String.IsNullOrEmpty(btmeItem.BTRST) && !String.IsNullOrEmpty(btmeItem.BTRED))
{
= btmeItem.BTSTM;
= btmeItem.BTETM;
= btmeItem.BTRST;
= btmeItem.BTRED;
}
// 若員工班表沒有設定,則取專案預設班表
else
{
// 取員工專案年度接單編號
var rapyn = bpsnDao.GetProjectByDate(, );
if (!String.IsNullOrEmpty(rapyn))
{
// 取專案預設班表編號
var bptme = bpaaDao.GetTimeTableNo(rapyn);
if (!String.IsNullOrEmpty(bptme))
{
// 取班表
btmeItem = btmeDao.SelectOne(bptme).FirstOrDefault();
if (btmeItem != null && !String.IsNullOrEmpty(btmeItem.BTSTM) && !String.IsNullOrEmpty(btmeItem.BTETM)
&& !String.IsNullOrEmpty(btmeItem.BTRST) && !String.IsNullOrEmpty(btmeItem.BTRED))
{
= btmeItem.BTSTM;
= btmeItem.BTETM;
= btmeItem.BTRST;
= btmeItem.BTRED;
}
}
}
}
= (, ) - (, );
= (, );
}
public static int (int )
{
double = ((double) / 30d) % 1d;
if ( > 0.5d)
return ( / 60 + 1) * 60;
else
return ( / 60) * 60;
}
public static int (int )
{
double = ((double) / 15d) % 1d;
if ( > 0.5d)
return ( / 30 + 1) * 30;
else
return ( / 30) * 30;
}
public static int (string tm1, string tm2)
{
DateTime dt1 = new DateTime();
DateTime dt2 = new DateTime();
dt1 = dt1.AddHours(Convert.ToInt32((tm1 + "00:00").Substring(0, 2))).AddMinutes(Convert.ToInt32((tm1 + "00:00").Substring(3, 2)));
dt2 = dt2.AddHours(Convert.ToInt32((tm2 + "00:00").Substring(0, 2))).AddMinutes(Convert.ToInt32((tm2 + "00:00").Substring(3, 2)));
return Convert.ToInt32((dt2 - dt1).TotalMinutes);
}
public static string (string tm1, int minutes)
{
DateTime dt1 = new DateTime();
dt1 = dt1.AddHours(Convert.ToInt32((tm1 + "00:00").Substring(0, 2))).AddMinutes(Convert.ToInt32((tm1 + "00:00").Substring(3, 2)));
dt1 = dt1.AddMinutes(minutes);
return dt1.ToString("HH:mm");
}
public int (string , string )
{
if (.CompareTo() <= 0 && .CompareTo() >= 0)
return ;
else if (.CompareTo() >= 0 && .CompareTo() <= 0 && .CompareTo() >= 0)
return (, );
else if (.CompareTo() <= 0 && .CompareTo() >= 0 && .CompareTo() <= 0)
return (, );
else if (.CompareTo() >= 0 && .CompareTo() <= 0 && .CompareTo() >= 0 && .CompareTo() <= 0)
return (, );
else
return 0;
}
public int (string , DateTime , DateTime , string , string , string , bool is進整小時)
{
Init(, );
if (String.IsNullOrEmpty())
= ;
if (String.IsNullOrEmpty())
= ;
int ;
// 起始與結束同一天
if ( == )
{
= (, ) - (, );
}
// 起始與結束不同天
else
{
DateTime std = ;
= 0;
while (std <= )
{
Init(, std);
// 不是假日,或是產假,要列入時數計算
if (!bhrdDao.IsHoliday(, std) || == RPAR_TYPE.T05_產假)
{
// 第一天
if (std == )
{
+= (, ) - (, );
}
// 最後一天
else if (std == )
{
+= (, ) - (, );
}
// 中間其他天
else
{
+= ;
}
}
std = std.AddDays(1);
}
}
if (is進整小時)
= ();
return ;
}
public int (string , DateTime , DateTime , string )
{
// 起始與結束同一天
if ( == )
{
return 1;
}
// 起始與結束不同天
else
{
DateTime std = ;
int = 0;
while (std <= )
{
// 不是假日,或是產假,要列入時數計算
if (!bhrdDao.IsHoliday(, std) || == RPAR_TYPE.T05_產假)
{
++;
}
std = std.AddDays(1);
}
return ;
}
}
public int (string , DateTime , DateTime , DateTime , string , string , string , bool is進整小時)
{
int = 0;
// 起始與結束同一天
if ( == )
{
Init(, );
if (String.IsNullOrEmpty())
= ;
if (String.IsNullOrEmpty())
= ;
= (, ) - (, );
if (is進整小時)
return ();
else
return ;
}
// 起始與結束不同天
else
{
DateTime std = ;
while (std <= )
{
Init(, std);
// 不是假日,或是產假,要列入時數計算
if (!bhrdDao.IsHoliday(, std) || == RPAR_TYPE.T05_產假)
{
// 第一天
if (std == )
{
= (, ) - (, );
}
// 最後一天
else if (std == )
{
= (, ) - (, );
}
// 中間其他天
else
{
= ;
}
// 只計算一天,就返回
if ( == std)
{
if (is進整小時)
return ();
else
return ;
}
}
else
= 0;
std = std.AddDays(1);
}
return 0;
}
}
public int (string , DateTime , string , string , bool )
{
Init(, );
int = (, ) - (, );
// 2018/3/1 之後休息日加班不進整 4 小時
if ( && .CompareTo(new DateTime(2018, 3, 1)) < 0)
= (int)(Math.Ceiling((decimal) / 240m) * 240m);
return ;
}
//public static void 拆分加班時數(int 分鐘數, bool 是假日, out int 前二, out int 後二, out int 假日)
//{
// 前二 = 0;
// 後二 = 0;
// 假日 = 0;
// if (是假日)
// 假日 = 分鐘數;
// else
// {
// if (分鐘數 < 120)
// 前二 = 分鐘數;
// else
// {
// 前二 = 120;
// 後二 = 分鐘數 - 120;
// }
// }
//}
public int (string , DateTime , DateTime , string , string )
{
Init(, );
if (String.IsNullOrEmpty())
= ;
if (String.IsNullOrEmpty())
= ;
int ;
// 起始與結束同一天
if ( == )
{
= (, ) - (, );
}
// 起始與結束不同天
else
{
DateTime std = ;
= 0;
while (std <= )
{
Init(, std);
// 第一天
if (std == )
{
+= (, ) - (, );
}
// 最後一天
else if (std == )
{
+= (, ) - (, );
}
// 中間其他天
else
{
+= ;
}
std = std.AddDays(1);
}
}
return ;
}
public int (string , DateTime , DateTime , DateTime , string , string )
{
Init(, );
if (String.IsNullOrEmpty())
= ;
if (String.IsNullOrEmpty())
= ;
int ;
// 起始與結束同一天
if ( == )
{
= (, ) - (, );
if ( == )
return ;
else
return 0;
}
// 起始與結束不同天
else
{
DateTime std = ;
while (std <= )
{
Init(, std);
= 0;
// 第一天
if (std == )
{
= (, ) - (, );
}
// 最後一天
else if (std == )
{
= (, ) - (, );
}
// 中間其他天
else
{
= ;
}
if ( == std)
return ;
std = std.AddDays(1);
}
}
return 0;
}
public static DateTime (string , DateTime , string )
{
// 解析30小時制(小時可能 >= 24,表示跨入隔日凌晨)
var parts = .Split(':');
var timeSpan = new TimeSpan(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]));
var sourceTime = .Date.Add(timeSpan);
if (string.IsNullOrEmpty() || string.Compare(, "Taipei Standard Time") == 0)
{
return sourceTime;
}
// 重要:將 Kind 設為 Unspecified
sourceTime = DateTime.SpecifyKind(sourceTime, DateTimeKind.Unspecified);
// 轉換到目標時區
var sourceZone = TimeZoneInfo.FindSystemTimeZoneById("Taipei Standard Time");
var targetZone = TimeZoneInfo.FindSystemTimeZoneById();
var utcTime = TimeZoneInfo.ConvertTimeToUtc(sourceTime, sourceZone);
var targetTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, targetZone);
return targetTime;
}
public static string (string , DateTime , string )
{
var targetTime = (, , );
// 輸出 30 小時制時分秒
// 06:00 之前算前一天,小時數加 24
int outputHours = targetTime.Hour;
if (targetTime.TimeOfDay < new TimeSpan(6, 0, 0))
outputHours += 24;
return string.Format("{0:00}:{1:00}:{2:00}", outputHours, targetTime.Minute, targetTime.Second);
}
}
/// <summary>
/// 30 小時制的日期類別
/// </summary>
public class DateAndTime
{
/// <summary>
/// 台灣工作日期
/// </summary>
public DateTime TwWorkDate;
/// <summary>
/// 台灣日曆日期
/// </summary>
public DateTime TwCalendarDate;
/// <summary>
/// 台灣時間
/// </summary>
public string TwTime;
/// <summary>
/// 當地日期
/// </summary>
public DateTime LocalDate;
/// <summary>
/// 當地時間
/// </summary>
public string LocalTime;
/// <summary>
/// 時區名稱
/// </summary>
public string TimezoneName;
/// <summary>
/// 時區ID
/// </summary>
public string TimeZoneID;
/// <summary>
/// 打卡的日期
/// </summary>
public DateTime CardDate;
public DateAndTime(DateTime twWorkDate, DateTime twCalendarDate, string twTime, DateTime localDate, string localTime, string timezoneName, string timezoneID) : base()
{
TwWorkDate = twWorkDate;
TwCalendarDate = twCalendarDate;
TwTime = twTime;
LocalDate = localDate;
LocalTime = localTime;
TimezoneName = timezoneName;
TimeZoneID = timezoneID;
CardDate = string.IsNullOrEmpty(TimeZoneID) || string.Compare(TimeZoneID, "Taipei Standard Time") == 0
? TwWorkDate
: TwCalendarDate;
}
public static DateAndTime GetNow(string bpeno)
{
var twNow = DateTime.UtcNow.AddHours(8);
var rasnDao = new RasnDAC(WGuard1.Query);
string timezoneID;
string timezoneName;
rasnDao.GetTimeZone(bpeno, twNow, out timezoneID, out timezoneName);
var twCalendarDate = twNow.Date;
var twWorkDate = twNow.Date;
var localNow = TimeCalc.(timezoneID, twNow.Date, twNow.ToString("HH:mm:ss"));
var localDate = localNow.Date;
var twHourOffset = 0;
var localHourOffset = 0;
// 06:00 之前算前一天
if (twNow.TimeOfDay < new TimeSpan(6, 0, 0))
{
twWorkDate = twWorkDate.AddDays(-1);
twHourOffset = 24;
}
if (localNow.TimeOfDay < new TimeSpan(6, 0, 0))
{
localDate = localDate.AddDays(-1);
localHourOffset = 24;
}
return new DateAndTime(
twWorkDate,
twCalendarDate,
string.Format("{0:00}:{1:00}:{2:00}", twNow.TimeOfDay.Hours + twHourOffset, twNow.TimeOfDay.Minutes, twNow.Second),
localDate,
string.Format("{0:00}:{1:00}:{2:00}", localNow.TimeOfDay.Hours + localHourOffset, localNow.TimeOfDay.Minutes, localNow.Second),
timezoneName,
timezoneID
);
}
}