CEL_Payroll/Payroll.BO/Process/BonusCalculator.cs

1004 lines
50 KiB
C#
Raw Normal View History

2024-09-17 14:30:13 +06:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ease.CoreV35;
using Ease.CoreV35.Model;
using Ease.CoreV35.Caching;
using System.Data.Linq.Mapping;
using Payroll.BO;
using System.Windows.Forms;
namespace Payroll.BO
{
public delegate void ProcessStatus1(string processStatus);
public delegate void ProgressStatus1(EnumProcessStatus status);
public delegate void ErrorMessage1(String error);
[Serializable]
public class BonusCalculator
{
public event ProcessStatus1 ProcessStatus;
public event ProgressStatus1 ProgressStatus;
private double _nEmpBasic = 0;
public BonusCalculator()
{
}
private void UpdateprocessStatus(string statusString)
{
if (ProcessStatus != null) ProcessStatus(statusString);
}
private void UpdateProgressStatus(EnumProcessStatus status)
{
if (ProgressStatus != null) ProgressStatus(status);
}
public void BCalculate(ObjectsTemplate<Employee> oEmployees,ID BonusID,DateTime payDate)
{
}
public double ConvertToDailyRate(double nBasic, DateTime dMonthDate)
{
double amount = 0;
amount = nBasic / Convert.ToDouble(DateTime.DaysInMonth(dMonthDate.Year, dMonthDate.Month));
return amount;
}
public double GeneralAmount(Employee oEmp, BonusParameter oBParameter, DateTime SalaryMonthDate)
{
double nTotalBonus = 0.0;
nTotalBonus = oBParameter.FlatAmount + (oEmp.GrossSalary * oBParameter.NoOfGross) + (oEmp.BasicSalary * oBParameter.NoOfBasic) + (oEmp.GrossSalary * oBParameter.PercentOfGross / 100) + (oEmp.BasicSalary * oBParameter.NoOfEarnedBasic);
// nTotalBonus = nTotalBonus + ConvertToDailyRate(oEmp.BasicSalary, SalaryMonthDate) * oBParameter.NoOfDays + ConvertToDailyRate(oEmp.GrossSalary, SalaryMonthDate) * oBParameter.GrossOfDays;
return nTotalBonus;
}
public double GeneralAmount(Employee oEmp,BonusParameter oBParameter, double basicSalary, double GrossSalary )
{
double nTotalBonus = 0.0;
nTotalBonus = oBParameter.FlatAmount +(GrossSalary *oBParameter.NoOfGross) + (basicSalary * oBParameter.NoOfBasic) + (GrossSalary * oBParameter.PercentOfGross / 100) + (basicSalary * oBParameter.NoOfEarnedBasic);
// nTotalBonus = nTotalBonus + ConvertToDailyRate(oEmp.BasicSalary, SalaryMonthDate) * oBParameter.NoOfDays + ConvertToDailyRate(oEmp.GrossSalary, SalaryMonthDate) * oBParameter.GrossOfDays;
return nTotalBonus;
}
/// <summary>
///
/// /// </summary>
/// <param name="oBonusPSalaryItem"></param>
/// <param name="oEmp"></param>
/// <param name="dSalaryMonth"></param>
/// <returns></returns>
public double CaculatedSalaryComponentAmount(BonusParameter parameter,Employee oEmp)
{
ObjectsTemplate<SalaryComponent> _SalaryComponents = SalaryComponent.Benefits();
double nAmount = 0;
int nProjectedMonth=0;
if (SalaryMonthly.IsSalaryProcessed(oEmp.ID, SystemInformation.CurrentSysInfo.NextPayProcessDate))
{
nProjectedMonth = Ease.CoreV35.Utility.Global.DateFunctions.DateDiff("m", SystemInformation.CurrentSysInfo.NextPayProcessDate,
Ease.CoreV35.Utility.Global.DateFunctions.LastDateOfYear(SystemInformation.CurrentSysInfo.NextPayProcessDate));
}
else
{
nProjectedMonth = Ease.CoreV35.Utility.Global.DateFunctions.DateDiff("m", SystemInformation.CurrentSysInfo.NextPayProcessDate,
Ease.CoreV35.Utility.Global.DateFunctions.LastDateOfYear(SystemInformation.CurrentSysInfo.NextPayProcessDate)) + 1;
}
//SalaryMonthly.IsSalaryProcessed();
double nTotalAmount = 0;
foreach (BonusParameter.BonusParamSalaryItem oSComponent in parameter.BonusParamSalaryItems)
{
SalaryMonthly osalary = new SalaryMonthly();
nAmount = osalary.GetAmountOnRange(oEmp, new DateTime(SystemInformation.CurrentSysInfo.NextPayProcessDate.Year, 1, 1), SystemInformation.CurrentSysInfo.NextPayProcessDate,
EnumSalaryGroup.Gross, (EnumSalaryItemCode)oSComponent.SalaryGroupCode, oSComponent.AllowDeductID, parameter.ID.Integer);
if (nProjectedMonth > 1)
nAmount = nAmount + (nProjectedMonth * oEmp.BasicSalary);
if(oSComponent.Percent>0)
nAmount = (nAmount * oSComponent.Percent) / 100;
nTotalAmount = nTotalAmount + nAmount;
}
return nTotalAmount;
}
public double CalculateOverTheYearAmount(BonusParameter oBonusParameter, Employee oEmp,DateTime dPayDate,double TotalBonusAmount)
{
double BonusOvertheAmount = 0.0;
DateTime JoiningDate = oEmp.JoiningDate;
DateTime CompareDate=DateTime.Now;
DateTime FirstDateofYear= Ease.CoreV35.Utility.Global.DateFunctions.FirstDateOfYear(dPayDate);
DateTime LastDateofYear = Ease.CoreV35.Utility.Global.DateFunctions.LastDateOfYear(dPayDate);
if(oEmp.JoiningDate<=FirstDateofYear)
{
CompareDate = FirstDateofYear;
}
if(CompareDate<=FirstDateofYear)
{
BonusOvertheAmount = TotalBonusAmount;
}
else if(JoiningDate>FirstDateofYear)
{
int nDays = (LastDateofYear - JoiningDate).Days + 1;
BonusOvertheAmount = (TotalBonusAmount * nDays) / 365;
}
return BonusOvertheAmount;
}
public double CalculateOverTheYearAmountForWartsila(BonusParameter oBonusParameter, Employee oEmp, DateTime cutOffDate, double TotalBonusAmount)
{
double BonusOvertheAmount = 0.0;
TimeSpan ts = cutOffDate.Subtract(oEmp.JoiningDate);
int tdays = ts.Days + 1;
if (tdays >= 180 && tdays <= 364)
{
BonusOvertheAmount = (TotalBonusAmount * tdays) / 365;
}
else if (tdays >= 365)
{
BonusOvertheAmount = TotalBonusAmount;
}
//if (oEmp.JoiningDate > FirstDateofYear)
//{
// int nDays = (LastDateofYear - JoiningDate).Days + 1;
// BonusOvertheAmount = (TotalBonusAmount * nDays) / 365;
//}
return BonusOvertheAmount;
}
public double CaculatedProratedCutOffAmount(BonusParameter oBonusParameter, Employee oEmp, double TotalBonusAmount, DateTime dCuttOffDate)
{
double BonusProAmount = 0.0;
DateTime JoiningDate = oEmp.JoiningDate;
DateTime CompareDate = DateTime.Now;
DateTime FirstDateofYear = Ease.CoreV35.Utility.Global.DateFunctions.FirstDateOfYear(dCuttOffDate);
DateTime LastDateofYear = Ease.CoreV35.Utility.Global.DateFunctions.LastDateOfYear(dCuttOffDate);
if (JoiningDate <= FirstDateofYear)
{
CompareDate = FirstDateofYear;
}
else if (JoiningDate > FirstDateofYear)
{
CompareDate = JoiningDate;
}
BonusProAmount = TotalBonusAmount * ((dCuttOffDate - CompareDate).Days + 1) / ((dCuttOffDate - FirstDateofYear).Days + 1);
return BonusProAmount;
}
public double CaculatedProratedAmount(BonusParameter oBonusParameter, Employee oEmp, double TotalBonusAmount, DateTime dCuttOffDate)
{
double BonusProAmount = 0.0;
DateTime JoiningDate = oEmp.JoiningDate;
DateTime CompareDate = DateTime.Now;
DateTime FirstDateofYear = Ease.CoreV35.Utility.Global.DateFunctions.FirstDateOfYear(dCuttOffDate);
DateTime LastDateofYear = Ease.CoreV35.Utility.Global.DateFunctions.LastDateOfYear(dCuttOffDate);
if (oEmp.JoiningDate <= FirstDateofYear)
{
CompareDate = FirstDateofYear;
}
if (CompareDate <= FirstDateofYear)
{
BonusProAmount = TotalBonusAmount;
}
else if (JoiningDate > FirstDateofYear)
{
int nDays = (LastDateofYear - JoiningDate).Days + 1;
BonusProAmount = (TotalBonusAmount * nDays) / 365;
}
return BonusProAmount;
}
public double CaculatedServiceLengthAmount(BonusParameter oBonusParameter,Employee oEmp,double TotalBonusAmount,DateTime dCuttOffDate)
{
DateTime toDate = DateTime.Now;
DateTime joiningDate = oEmp.JoiningDate;
double BonusSLengthAmount = 0.0;
int ServiceLength = 0;
int Counter = 0;
// if paramter applicable cutt of date, other wise deduct from last date of year.
Counter = (dCuttOffDate - joiningDate).Days + 1;
if (oBonusParameter.BonusServiceLengths != null)
{
for (int i = oBonusParameter.BonusServiceLengths.Count; i >=1 ; i--)
{
// ServiceLength = oBonusParameter.BonusServiceLengths[i-1].LengthOfService;
if (oBonusParameter.BonusServiceLengths[i-1].LengthOfService < Counter)
{
ServiceLength = oBonusParameter.BonusServiceLengths[i - 1].EntitlePercent;
break;
}
}
BonusSLengthAmount = (TotalBonusAmount * ServiceLength)/100;
}
return BonusSLengthAmount;
}
public double CalculationSlabOnBasic(BonusParameter oBonusParameter, Employee oEmp, double basicSalary)
{
double BonusDearnessAmount=0.0;
if (oBonusParameter.BonusSlabs != null)
{
for (int i = oBonusParameter.BonusSlabs.Count; i >= 1; i--)
{
if (oBonusParameter.BonusSlabs[i - 1].SlabAmount < basicSalary)
{
if(oBonusParameter.BonusSlabs[i - 1].AmountType==EnumSlabAmountType.ActualBasic)
{
BonusDearnessAmount = basicSalary;
break;
}
else if (oBonusParameter.BonusSlabs[i - 1].AmountType == EnumSlabAmountType.FlatAmount)
{
BonusDearnessAmount = oBonusParameter.BonusSlabs[i - 1].Amount;
break;
}
}
}
}
return BonusDearnessAmount;
}
public double CalculationCasualBonusAmount(BonusParameter oBonusParameter, Employee oEmp, double basicSalary)
{
double BonusCasualAmount = 0.0;
ObjectsTemplate<EmpLeaveStatus> oEmpLStatuses = EmpLeaveStatus.EmpCurrentYearStatus(oEmp);
double nCLeave = 0;
//foreach(EmpLeaveStatus oEmpLStatus in oEmpLStatuses)
//{
// if(oEmpLStatus.LeaveId==5)
// {
// nCLeave = oEmpLStatus.LeaveAvailed;
// }
//}
if (oBonusParameter.BonusSlabs != null)
{
for (int i = oBonusParameter.BonusSlabs.Count; i >= 1; i--)
{
if (oBonusParameter.BonusSlabs[i - 1].SlabAmount < nCLeave)
{
if (oBonusParameter.BonusSlabs[i - 1].AmountType == EnumSlabAmountType.Percentage)
{
BonusCasualAmount = basicSalary * (oBonusParameter.BonusSlabs[i - 1].Amount / 100);//oBonusParameter.BonusSlabs[i - 1].Amount;
break;
}
}
}
}
return BonusCasualAmount;
}
//public double CaculatedBonusAdjustAmount(BonusParameter.BonusParamAdjustItem oBonusPAdjustAmount)
//{
// double BonusAdjustAmount = 0.0;
// if (oBonusParameter.BonusParamAdjustItems != null)
// {
// foreach (BonusParameter.BonusParamAdjustItem oBAdjustAmount in oBonusParameter.BonusParamAdjustItems)
// {
// BonusAdjustAmount += oBAdjustAmount.Amount;
// }
// }
// return BonusAdjustAmount;
//}
public double CalcluateBonus(BonusParameter param, Employee oemployee,
double basicSalary, double GrossSalary, DateTime dCuttOfDate)
{
double BonusGeneralAmount=0;
double TotalAmount=0;
double BonusAdjustAmount=0;
double BonusSalaryItemAmount=0;
double BonusDearnessAmount=0;
double BonusCasualAmount=0;
#region calculate adjust Item
//if (oBonusParm.BonusParamSalaryItems != null && oBonusParm.BonusParamSalaryItems.Count > 0)
// BonusSalaryItemAmount = this.CaculatedSalaryComponentAmount(oBonusParm, oEmp);
//foreach (BonusParameter.BonusParamAdjustItem oBPAdjustItem in oBonusParm.BonusParamAdjustItems)
//{
// BonusProcess.BonusProcessDetail.BonusProcessAdjustItem oBPAItem = new BonusProcess.BonusProcessDetail.BonusProcessAdjustItem();
// BonusAdjustAmount += oBPAdjustItem.Amount;
// oBPAItem.AdjustAmount = oBPAdjustItem.Amount;
// oBPAItem.BonusAdjustID = oBPAdjustItem.BonusAdjustItemID;
// oBPDetail.BonusProcessAdjustItems.Add(oBPAItem);
//}
#endregion calculate adjust Item
BonusGeneralAmount = this.GeneralAmount(oemployee, param, basicSalary, oemployee.GrossSalary);
bool bjoiningproporate = ConfigurationManager.GetBoolValue("bonus", "joiningprorate", EnumConfigurationType.Logic);
#region calculate Slab Amount
//if (oBonusParm.BonusSlabs.Count > 0)
//{
// if (oBonusParm.BonusSlabs[1].SlabType == EnumSlabType.BasicSalary)
// {
// BonusDearnessAmount = this.CalculationSlabOnBasic(oBonusParm, oEmp, nBasicSalary);
// }
// else if (oBonusParm.BonusSlabs[1].SlabType == EnumSlabType.CasualLeave)
// {
// BonusCasualAmount = this.CalculationCasualBonusAmount(oBonusParm, oEmp,nBasicSalary);
// }
//}
#endregion calculate Slab Amount
TotalAmount = BonusGeneralAmount + BonusAdjustAmount + BonusSalaryItemAmount + BonusDearnessAmount + BonusCasualAmount;
if (param.BonusServiceLengths != null && param.BonusServiceLengths.Count > 0)
TotalAmount = this.CaculatedServiceLengthAmount(param, oemployee, TotalAmount, dCuttOfDate);
else if (param.IsProrated && param.EligibleCuttoffDate)
TotalAmount = this.CaculatedProratedCutOffAmount(param, oemployee, TotalAmount, dCuttOfDate);
else if (param.IsProrated)
TotalAmount = this.CaculatedProratedAmount(param, oemployee, TotalAmount, dCuttOfDate);
return TotalAmount;
}
public static double GetGrossAmount(Employee oEmp, ObjectsTemplate<ADParameter> adParamsAll, ObjectsTemplate<ADParameterEmployee> adParamEmpsAll, ObjectsTemplate<GrossDefination> grossDefinitions, DateTime dEffectDate, EmployeeGradeSalary oEmpGradeSal)
{
List<ADParameter> adParams = null;
List<ADParameterEmployee> adParamEmps = null;
ObjectsTemplate<ADParameter> applicableParams = new ObjectsTemplate<ADParameter>();
EmployeeGradeSalary oEmpGSalary = new EmployeeGradeSalary();
double nAmount = 0;
double nBasicSalary = 0;
//EmployeeGradeSalary oEmpGradeSal = EmployeeGradeSalary.GetBasicOnDate(oEmp.ID, dEffectDate);
if (oEmpGradeSal == null) return 0;
if(oEmpGradeSal!=null)
{
nAmount=oEmpGradeSal.BasicSalary;
oEmp.BasicSalary = nAmount;
}
adParams = adParamsAll.FindAll(x => x.EntitleType == EnumEntitleType.Grade && x.AllowOrDeductType == EnumAllowOrDeduct.Allowance);
if (adParams != null)
{
foreach (ADParameter adParam in adParams)
{
GrossDefination gDef = grossDefinitions.Find(x => x.BenefitDefinationType == EnumBenefitDefinationType.Gross && x.ComponentID == adParam.AllowDeductID);
if (gDef != null)
{
ADParameter.ADParameterGrade adGrade = adParam.ADParameterGrades.Find(x => x.GradeID == oEmp.GradeID);
if (adGrade != null)
{
double dd = adParam.GetGradeDefinedAmount(oEmp,
oEmpGradeSal.BasicSalary,
oEmpGradeSal.GrossSalary, oEmpGradeSal);
nAmount += dd==null?0:dd * gDef.Quantity;
}
}
}
}
adParamEmps = adParamEmpsAll.FindAll(x => x.ADEmpType == EnumADEmpType.AppliedToIndividual);
if (adParamEmps != null)
{
foreach (ADParameterEmployee adEmp in adParamEmps)
{
GrossDefination gDef = grossDefinitions.Find(x => x.BenefitDefinationType == EnumBenefitDefinationType.Gross && x.ComponentID == adEmp.AllowDeductID);
if (gDef != null)
{
if (adEmp.EmployeeID == oEmp.ID)
{
nAmount += adEmp.MonthlyAmount * gDef.Quantity;
}
}
}
}
return (nAmount * 12) + oEmpGradeSal.BasicSalary*2;
}
public static double GetMonthlyGrossAmount(Employee oEmp, ObjectsTemplate<ADParameter> adParamsAll, ObjectsTemplate<ADParameterEmployee> adParamEmpsAll, ObjectsTemplate<GrossDefination> grossDefinitions, DateTime dEffectDate, EmployeeGradeSalary oEmpGradeSal)
{
List<ADParameter> adParams = null;
List<ADParameterEmployee> adParamEmps = null;
ObjectsTemplate<ADParameter> applicableParams = new ObjectsTemplate<ADParameter>();
EmployeeGradeSalary oEmpGSalary = new EmployeeGradeSalary();
double nAmount = 0;
double nBasicSalary = 0;
//EmployeeGradeSalary oEmpGradeSal = EmployeeGradeSalary.GetBasicOnDate(oEmp.ID, dEffectDate);
if (oEmpGradeSal == null) return 0;
if (oEmpGradeSal != null)
{
nAmount = oEmpGradeSal.BasicSalary;
oEmp.BasicSalary = nAmount;
}
adParams = adParamsAll.FindAll(x => x.EntitleType == EnumEntitleType.Grade && x.AllowOrDeductType == EnumAllowOrDeduct.Allowance);
if (adParams != null)
{
foreach (ADParameter adParam in adParams)
{
GrossDefination gDef = grossDefinitions.Find(x => x.BenefitDefinationType == EnumBenefitDefinationType.Gross && x.ComponentID == adParam.AllowDeductID);
if (gDef != null)
{
ADParameter.ADParameterGrade adGrade = adParam.ADParameterGrades.Find(x => x.GradeID == oEmp.GradeID);
if (adGrade != null)
{
double dd = adParam.GetGradeDefinedAmount(oEmp,
oEmpGradeSal.BasicSalary,
oEmpGradeSal.GrossSalary, oEmpGradeSal);
nAmount += dd == null ? 0 : dd * gDef.Quantity;
}
}
}
}
adParamEmps = adParamEmpsAll.FindAll(x => x.ADEmpType == EnumADEmpType.AppliedToIndividual);
if (adParamEmps != null)
{
foreach (ADParameterEmployee adEmp in adParamEmps)
{
GrossDefination gDef = grossDefinitions.Find(x => x.BenefitDefinationType == EnumBenefitDefinationType.Gross && x.ComponentID == adEmp.AllowDeductID);
if (gDef != null)
{
if (adEmp.EmployeeID == oEmp.ID)
{
nAmount += adEmp.MonthlyAmount * gDef.Quantity;
}
}
}
}
//return (nAmount) + ((oEmpGradeSal.BasicSalary * 2)/12);
return Math.Round(nAmount);
}
public static double GetMonthlyGrossAmount(Employee oEmp, ObjectsTemplate<ADParameter> adParamsAll, ObjectsTemplate<ADParameterEmployee> adParamEmpsAll, ObjectsTemplate<GrossDefination> grossDefinitions, DateTime dEffectDate)
{
List<ADParameter> adParams = null;
List<ADParameterEmployee> adParamEmps = null;
ObjectsTemplate<ADParameter> applicableParams = new ObjectsTemplate<ADParameter>();
EmployeeGradeSalary oEmpGSalary = new EmployeeGradeSalary();
double nAmount = 0;
double nBasicSalary = 0;
EmployeeGradeSalary oEmpGradeSal = EmployeeGradeSalary.GetBasicOnDate(oEmp.ID, dEffectDate);
if (oEmpGradeSal == null) return 0;
if (oEmpGradeSal != null)
{
nAmount = oEmpGradeSal.BasicSalary;
}
adParams = adParamsAll.FindAll(x => x.EntitleType == EnumEntitleType.Grade && x.AllowOrDeductType == EnumAllowOrDeduct.Allowance);
if (adParams != null)
{
foreach (ADParameter adParam in adParams)
{
GrossDefination gDef = grossDefinitions.Find(x => x.BenefitDefinationType == EnumBenefitDefinationType.Gross && x.ComponentID == adParam.AllowDeductID);
if (gDef != null)
{
ADParameter.ADParameterGrade adGrade = adParam.ADParameterGrades.Find(x => x.GradeID == oEmp.GradeID);
if (adGrade != null)
{
double dd = adParam.GetGradeDefinedAmount(oEmp,
oEmpGradeSal.BasicSalary,
oEmpGradeSal.GrossSalary, oEmpGradeSal);
nAmount += dd == null ? 0 : dd * gDef.Quantity;
}
}
}
}
adParamEmps = adParamEmpsAll.FindAll(x => x.ADEmpType == EnumADEmpType.AppliedToIndividual);
if (adParamEmps != null)
{
foreach (ADParameterEmployee adEmp in adParamEmps)
{
GrossDefination gDef = grossDefinitions.Find(x => x.BenefitDefinationType == EnumBenefitDefinationType.Gross && x.ComponentID == adEmp.AllowDeductID);
if (gDef != null)
{
if (adEmp.EmployeeID == oEmp.ID)
{
nAmount += adEmp.MonthlyAmount * gDef.Quantity;
}
}
}
}
return (nAmount) + (oEmpGradeSal.BasicSalary * 2)/12;
}
public BonusProcess CalCulate(ObjectsTemplate<Employee> oEmployees, Bonus oBonus, DateTime dBasicMonth,
DateTime dPayDate, DateTime dCuttOfDate, double CurrProcess, bool IsDisburseWithSalary, bool IsTaxProcess,EnumFestivalType efestivaltype,int religionID,int nQuarterID,DateTime bonusDate)
{
//Added by ashek to reduce database hits
string bonusProcessIDs = string.Empty;
ObjectsTemplate<BonusProcess> _bonusProcess = BonusProcess.GetProcess();
ObjectsTemplate<BonusProcess> _bonusProcessTemp = new ObjectsTemplate<BonusProcess>();
List<EnmSetupManagerTranType> oSetupManagerTranTypes = SetupDetail.GetTypes(EnumParameterSetup.Bonus);
ObjectsTemplate<SetupDetail> oSetupDetails = SetupDetail.GetParameters(EnumParameterSetup.Bonus);
bool CheckOvertheYearCal = ConfigurationManager.GetBoolValue("bonus", "overtheyearcalculation", EnumConfigurationType.Logic);
ObjectsTemplate<BonusParameter> paramAll = BonusParameter.Get(EnumStatus.Active);
int nTotal = oEmployees.Count;
BonusProcess oProssBonus = new BonusProcess();
oProssBonus.BonusProcessDetails = new ObjectsTemplate<BonusProcess.BonusProcessDetail>();
double nBasicSalary = 0;
double nGrossSalary = 0;
//ObjectsTemplate<ADParameter> adParams = ADParameter.Get(EnumStatus.Active);
//ObjectsTemplate<ADParameterEmployee> adParamEmps = ADParameterEmployee.Get(EnumStatus.Active);
ObjectsTemplate<GrossDefination> grossDefinitions = GrossDefination.Get();
List<EmployeeGradeSalary> grdSals = EmployeeGradeSalary.Get();
dBasicMonth = GlobalFunctions.LastDateOfMonth(dBasicMonth);
UpdateprocessStatus("Calculating Bonus");
UpdateProgressStatus(EnumProcessStatus.Start);
int nCount = 0;
try
{
foreach (Employee oEmp in oEmployees)
{
nCount++;
if (oEmp.JoiningDate > dBasicMonth) continue;
UpdateprocessStatus("Calculating Bonus " + nCount.ToString() + "/" + nTotal.ToString());
UpdateProgressStatus(EnumProcessStatus.PerformStep);
double TotalAmount = 0;
double nGrossPaid = 0;
//EmployeeGradeSalary ogs = null;
EmployeeGradeSalary ogs = EmployeeGradeSalary.GetBasicOnDate(oEmp.ID, dBasicMonth);
//List<EmployeeGradeSalary> gg= grdSals.FindAll(x => x.EmployeeID == oEmp.ID && x.EffectDate <= dBasicMonth);
//var nMaxID = (grdSals.FindAll(x => x.EmployeeID == oEmp.ID && x.EffectDate <= dBasicMonth)).Max(y => y.ID.Integer);
//if (nMaxID != 0) ogs = grdSals.Find(x => x.ID.Integer == nMaxID);
//oEmp.GradeID = ogs == null ? oEmp.GradeID : ogs.GradeID;
ObjectsTemplate<BonusParameter> oParams = BonusParameter.ApplicableParameters3(oEmp, oBonus.ID, oSetupManagerTranTypes, oSetupDetails, paramAll);
ObjectsTemplate<ADParameter> adParams = ADParameter.Get(oEmp.GradeID, EnumEntitleType.Grade, EnumAllowOrDeduct.Allowance);
ObjectsTemplate<ADParameterEmployee> adParamEmps = ADParameterEmployee.GetByEmployee(oEmp.ID, EnumAllowOrDeduct.Allowance, EnumADEmpType.AppliedToIndividual);
nGrossPaid = BonusCalculator.GetMonthlyGrossAmount(oEmp, adParams, adParamEmps, grossDefinitions, dBasicMonth, ogs);
if (oParams == null || oParams.Count <= 0)
continue;// throw new ServiceException("Parameter not found for the employee " + oEmp.Name + " (" + oEmp.EmployeeNo + ")");
//if (efestivaltype != EnumFestivalType.PartOne)
// oEmp.GrossSalary = GetGrossAmount(oEmp, adParams, adParamEmps, grossDefinitions, dBasicMonth, ogs);
foreach (BonusParameter oBonusParm in oParams)
{
if (ogs != null)
{
oEmp.BasicSalary = ogs.BasicSalary;
oEmp.GrossSalary = nGrossPaid;
}
#region prepare bonusProcess
_bonusProcessTemp = _bonusProcess.Where(o => o.BonusID == oBonusParm.BonusID && (o.BonusMonth>GlobalFunctions.FirstDateOfYear(dPayDate) && o.BonusMonth<GlobalFunctions.LastDateOfYear(dPayDate))).ToObjectsTemplate();
bonusProcessIDs = string.Join(",", _bonusProcessTemp.Select(x => x.ID.ToString()).ToList());
oProssBonus.BonusID = oBonusParm.BonusID;
oProssBonus.UsedProcess = CurrProcess;
oProssBonus.BasicOnMonth = GlobalFunctions.LastDateOfMonth(dBasicMonth);
oProssBonus.BonusMonth = Payroll.BO.SystemInformation.CurrentSysInfo.NextPayProcessDate;
oProssBonus.DisburseDate = GlobalFunctions.LastDateOfMonth(dPayDate);
oProssBonus.IsDisburseWithSalary = IsDisburseWithSalary;
oProssBonus.IsTaxProcess = IsTaxProcess;
oProssBonus.ReligionID = ID.FromInteger(religionID);
//EmployeeGradeSalary ogs = EmployeeGradeSalary.GetBasicOnDate(oEmp.ID, dBasicMonth);
if (ogs == null)
{
nBasicSalary = oEmp.BasicSalary;
// nGrossSalary = oEmp.GrossSalary;
}
else
{
nBasicSalary = ogs.BasicSalary;
// nGrossSalary = ogs.GrossSalary;
}
#endregion prepare bonusProcess
BonusProcess.BonusProcessDetail oBPDetail = new BonusProcess.BonusProcessDetail();
oBPDetail.BonusID = oBonusParm.BonusID;
oBPDetail.EmployeeID = oEmp.ID;
oBPDetail.BasicSalary = nBasicSalary;
oBPDetail.BonusMonth = GlobalFunctions.LastDateOfMonth(dPayDate);
oBPDetail.GrossSalary = oEmp.GrossSalary;
// oBPDetail.BonusMonth = Payroll.BO.SystemInformation.CurrentSysInfo.NextPayProcessDate;
if (oProssBonus.BonusID.Integer == 1)//Festival
{
TotalAmount = this.CalcluatefestivalBonus(oBonusParm, oEmp, nBasicSalary, oEmp.GrossSalary, dCuttOfDate, efestivaltype, religionID, dPayDate, dBasicMonth, ogs,bonusDate);
}
else if (oProssBonus.BonusID.Integer == 2 || oProssBonus.BonusID.Integer == 5 || oProssBonus.BonusID.Integer == 6 || oProssBonus.BonusID.Integer == 7)//KPI
{
//TotalAmount = this.CalcluateKPIBonus(oBonusParm, oEmp, nBasicSalary, oEmp.GrossSalary, dCuttOfDate, nQuarterID);
TotalAmount = this.CalcluateKPIBonus(oBonusParm, oEmp, nBasicSalary, oEmp.GrossSalary, dCuttOfDate, nQuarterID, bonusProcessIDs);
}
else if (oProssBonus.BonusID.Integer == 4)//Corporate
{
TotalAmount = this.CalcluateCorporateBonus(oBonusParm, oEmp, nBasicSalary, oEmp.GrossSalary, dBasicMonth);
}
else
{
TotalAmount = this.CalcluateBonus(oBonusParm, oEmp, nBasicSalary, nGrossSalary, dBasicMonth);
}
if (oBonusParm.IsOverYearCalculation)
{
double noOfItem = oBonusParm.NoOfBasic + oBonusParm.NoOfGross;
double preAmount = BonusProcess.GetBonusAmountWithinYear(dBasicMonth, oEmp.ID, oBonusParm.BonusID.Integer);
if (preAmount > 0)
{
int nNoOfPaid = BonusProcess.GetForNoOfPaidForEmp(dBasicMonth, oBonusParm.BonusID.Integer, oEmp.ID.Integer);
oBPDetail.BonusAmount = (TotalAmount - preAmount) * CurrProcess / (oBonusParm.NoOfDisbusement - nNoOfPaid);
}
else
{
oBPDetail.BonusAmount = TotalAmount / oBonusParm.NoOfDisbusement * CurrProcess;
}
}
//else if (oBonusParm.PercentOfGross >0)
// oBPDetail.BonusAmount = (TotalAmount / oBonusParm.PercentOfGross) * CurrProcess;
//else if (oBonusParm.IsPercent() == true)
// oBPDetail.BonusAmount = (TotalAmount / 100) * CurrProcess;
//else
//{
// double noOfItem = oBonusParm.NoOfBasic + oBonusParm.NoOfGross;
// oBPDetail.BonusAmount = TotalAmount / noOfItem * CurrProcess;
//}
TimeSpan ts = dCuttOfDate - oEmp.JoiningDate;
//if (efestivaltype == EnumFestivalType.PartOne || efestivaltype == EnumFestivalType.PartTwo || efestivaltype == EnumFestivalType.Other)
if (efestivaltype == EnumFestivalType.Other)
{
int nTotalDaysInYear = 365;
if (DateTime.IsLeapYear(Payroll.BO.SystemInformation.CurrentSysInfo.NextPayProcessDate.Year))
nTotalDaysInYear += 1;
if (ts.Days + 1 < nTotalDaysInYear)
TotalAmount = (TotalAmount / nTotalDaysInYear) * (ts.Days + 1);
}
else if (oProssBonus.BonusID.Integer == 2 || oProssBonus.BonusID.Integer == 5 || oProssBonus.BonusID.Integer == 6 || oProssBonus.BonusID.Integer == 7)//KPI
{
ts = dPayDate - oEmp.JoiningDate;
TimeSpan ts2 = new TimeSpan();
if (oProssBonus.BonusID.Integer == 2)
{
ts2 = new DateTime(dBasicMonth.Year, 3, 31) - new DateTime(dBasicMonth.Year, 1, 1);
}
else if (oProssBonus.BonusID.Integer == 5)
{
ts2 = new DateTime(dBasicMonth.Year, 6, 30) - new DateTime(dBasicMonth.Year, 4, 1);
}
else if (oProssBonus.BonusID.Integer == 6)
{
ts2 = new DateTime(dBasicMonth.Year, 9, 30) - new DateTime(dBasicMonth.Year, 7, 1);
}
else if (oProssBonus.BonusID.Integer == 7)
{
ts2 = new DateTime(dBasicMonth.Year, 12, 31) - new DateTime(dBasicMonth.Year, 10, 1);
}
if (ts.Days + 1 < ts2.Days)
TotalAmount = (TotalAmount / ts2.Days) * ts.Days + 1;
}
oBPDetail.BonusAmount = GlobalFunctions.Round(TotalAmount);
oBPDetail.ChangeBonusAmount = GlobalFunctions.Round(TotalAmount);
oBPDetail.IsProjectedBonus = oBonusParm.IsFestival;
oBPDetail.CalculatedAdjustAmount = oBonusParm.PercentOfGross;
oBPDetail.CalculatedSalaryItemAmount = oBonusParm.PerformanceBonusPercent;
//oBPDetail.ChangeAdjustAmount = BonusAdjustAmount;
//oBPDetail.ChangeSalaryItemAmount = BonusSalaryItemAmount;
if (oProssBonus.BonusID.Integer == 2 || oProssBonus.BonusID.Integer == 5 || oProssBonus.BonusID.Integer == 6 || oProssBonus.BonusID.Integer == 7)//KPI
{
BonusProcess.BonusProcessDetail.BonusProcessAdjustItem obj = new BonusProcess.BonusProcessDetail.BonusProcessAdjustItem();
oBPDetail.BonusProcessAdjustItems = new ObjectsTemplate<BonusProcess.BonusProcessDetail.BonusProcessAdjustItem>();
obj.BonusAdjustID = oProssBonus.BonusID.Integer;
obj.AdjustAmount = oBonusParm.Q2;
oBPDetail.BonusProcessAdjustItems.Add(obj);
}
oProssBonus.BonusProcessDetails.Add(oBPDetail);
}
}
UpdateProgressStatus(EnumProcessStatus.End);
return oProssBonus;
}
catch
{
nCount = nCount;
return oProssBonus;
}
// return oProssBonus;
}
private double CalcluatefestivalBonus(BonusParameter oBonusParm, Employee oEmp, double nBasicSalary, double nGrossSalary, DateTime dCuttOfDate, EnumFestivalType eFestivalType, int nReligionID, DateTime dPayDate, DateTime dBasicMonth,EmployeeGradeSalary ogs,DateTime bonusDate)
{
Double m_nAMOUNT = 0;
m_nAMOUNT = (nGrossSalary * oBonusParm.PercentOfGross) / 100;
//double nTotalBonus = 0;
//EmployeeGradeSalary oGradesalary = null;
//int nTotalDays = 0;
//int nTotalDays2 = 0;
//Double nEntitlements = 0;
//ObjectsTemplate<BonusProcess> oBonusProcesses = new ObjectsTemplate<BonusProcess>();
//BonusProcess oBonusProcess = new BonusProcess();
// int nNoOfDays = 0;
//DateTime dFromMonth;
//DateTime dToMonth;
//double nFirstBonus = 0;
//oGradesalary = new EmployeeGradeSalary();
//oGradesalary = EmployeeGradeSalary.Get(oEmp.ID, dBasicMonth);
//oGradesalary = ogs;
//_nEmpBasic = oGradesalary == null?0:oGradesalary.BasicSalary;
//if (eFestivalType == EnumFestivalType.PartOne)
//{
// dFromMonth = new DateTime(dCuttOfDate.Year, 1, 1);
// dToMonth = dToMonth = new DateTime(dCuttOfDate.Year, 12, 31);// new DateTime(dCuttOfDate.Year, 6, 30);
// //TimeSpan ts = dToMonth - dFromMonth;
// //nTotalDays = (int)ts.TotalDays + 1;// DateDiff("d", dFromMonth, dToMonth) + 1
// //ts = dToMonth - oEmp.JoiningDate;
// //nNoOfDays = (int)ts.TotalDays + 1;
// //if (nTotalDays < nNoOfDays)
// //{
// // nNoOfDays = nTotalDays;
// //}
// //nTotalBonus = (oGradesalary.BasicSalary * (nNoOfDays + nTotalDays)) / (nTotalDays * 2);
// TimeSpan ts = dToMonth - oEmp.JoiningDate;
// if (ts.TotalDays + 1 > 365)
// nNoOfDays = 365;
// else
// {
// nNoOfDays = (int)ts.TotalDays + 1;
// nNoOfDays = 365 - nNoOfDays;
// nNoOfDays = 365 - nNoOfDays;
// }
// //if (nTotalDays < nNoOfDays)
// //{
// // nNoOfDays = nTotalDays;
// //}
// nTotalBonus = (oGradesalary.BasicSalary / 365) * nNoOfDays;
// //if (nNoOfDays < 0)
// //{
// // nNoOfDays = 0;
// // dFromMonth = new DateTime(dCuttOfDate.Year, 7, 1);
// // dToMonth = new DateTime(dCuttOfDate.Year, 12, 31);
// // ts = dToMonth - dFromMonth;
// // nTotalDays = (int)ts.TotalDays + 1;
// // ts = dToMonth - oEmp.JoiningDate;
// // nNoOfDays = (int)ts.TotalDays + 1;
// // nTotalBonus = (nBasicSalary * (nNoOfDays)) / (nTotalDays * 2);
// //}
// m_nAMOUNT = nTotalBonus;
//}
//else if (eFestivalType == EnumFestivalType.PartTwo)
//{
// dFromMonth = new DateTime(dCuttOfDate.Year, 7, 1);
// dToMonth = new DateTime(dCuttOfDate.Year, 12, 31);
// TimeSpan ts = dToMonth - dFromMonth;
// nTotalDays = (int)ts.TotalDays + 1;// DateDiff("d", dFromMonth, dToMonth) + 1
// ts = dToMonth - oEmp.JoiningDate;
// nNoOfDays = (int)ts.TotalDays + 1;
// if (nTotalDays < nNoOfDays)
// {
// nNoOfDays = nTotalDays;
// }
// nFirstBonus = BonusProcess.GetBonusAmountWithinYear(GlobalFunctions.LastDateOfMonth(dPayDate), oEmp.ID, oBonusParm.BonusID.Integer,nReligionID);
// nTotalBonus =(_nEmpBasic * nNoOfDays) / nTotalDays ;
// m_nAMOUNT = nTotalBonus+(nTotalBonus- nFirstBonus);
//}
//else if (eFestivalType == EnumFestivalType.NonMuslim)
//{
// //nFirstBonus = BonusProcess.GetBonusAmountWithinYear(dCuttOfDate, oEmp.ID, oBonusParm.BonusID.Integer, nReligionID);
// dFromMonth = oEmp.JoiningDate;// new DateTime(dCuttOfDate.Year, 1, 1);
// dToMonth = dCuttOfDate;// new DateTime(dCuttOfDate.Year, 12, 31);
// TimeSpan ts2 = dToMonth - new DateTime(dCuttOfDate.Year, 1, 1);
// //dToMonth = dCuttOfDate;
// TimeSpan ts = dToMonth - dFromMonth;
// nTotalDays = (int)ts.TotalDays + 1;// DateDiff("d", dFromMonth, dToMonth) + 1
// if (nTotalDays < 356)
// {
// ts = dToMonth - oEmp.JoiningDate;
// nNoOfDays = (int)ts.TotalDays + 1;
// nTotalDays = 366;
// }
// else
// nNoOfDays = nTotalDays;
// //if (nTotalDays < nNoOfDays)
// //{
// // nNoOfDays = nTotalDays;
// //}
// nTotalBonus = (_nEmpBasic * 2 * nNoOfDays) / nTotalDays;
// m_nAMOUNT = nTotalBonus;
//}
//else if (eFestivalType == EnumFestivalType.Arrear)
//{
// ObjectsTemplate<BonusProcess.BonusProcessDetail> oDetails = BonusProcess.GetBonusDetails(bonusDate, oEmp.ID.Integer, oBonusParm.BonusID.Integer);
// if (oDetails != null && oDetails.Count > 0)
// {
// ogs= EmployeeGradeSalary.GetBasicOnDate(oEmp.ID, bonusDate);
// if(ogs!=null)
// {
// double nPaid = oDetails.Sum(x => x.BonusAmount);
// double nArrearAmount = ogs.BasicSalary * oDetails.Count;
// m_nAMOUNT = nArrearAmount - nPaid;
// if (m_nAMOUNT < 0) m_nAMOUNT = 0;
// }
// }
//}
return m_nAMOUNT;
}
private double CalcluateKPIBonus(BonusParameter oBonusParm, Employee oEmp, double nBasicSalary, double nGrossSalary, DateTime dCuttOfDate, int nQuarterID, string bonusProcessIDs)
{
Double m_nAMOUNT = 0;
double nPercent = 0;
double nAnnualGrossPencentage = oBonusParm.PercentOfGross;
double nPerformancePercentage = oBonusParm.PerformanceBonusPercent;
nPercent = oBonusParm.Q1;
//switch(nQuarterID)
//{
// case 250:
// nPercent = oBonusParm.Q2;
// break;
// case 260:
// nPercent = oBonusParm.Q1;
// break;
//}
m_nAMOUNT = ((nGrossSalary * nAnnualGrossPencentage) / 100);
m_nAMOUNT = ((m_nAMOUNT * nPerformancePercentage) / 100);
m_nAMOUNT = m_nAMOUNT / 4;
m_nAMOUNT = ((m_nAMOUNT * nPercent) / 100);
//Previous
double PrevBonus = 0;
if (bonusProcessIDs == string.Empty)
PrevBonus = 0;
else
PrevBonus = BonusProcess.GetPreviousKPIBonusAmount(oEmp.ID, oBonusParm.BonusID.Integer, bonusProcessIDs);
//double prevPercent=0;
//double prevAmount = 0;
//if(PrevBonus>0)
//{
// prevPercent = BonusProcess.GetKPIBonusAmountWithinYearPercent(dCuttOfDate, oEmp.ID, oBonusParm.BonusID.Integer, oBonusParm.BonusID.Integer);
// prevAmount = ((nGrossSalary * nAnnualGrossPencentage) / 100);
// prevAmount = ((prevAmount * nPerformancePercentage) / 100);
// prevAmount = prevAmount / 4;
// prevAmount = ((prevAmount * prevPercent) / 100);
//}
return (m_nAMOUNT) - PrevBonus;
}
private double CalcluateKPIBonus(BonusParameter oBonusParm, Employee oEmp, double nBasicSalary, double nGrossSalary, DateTime dCuttOfDate, int nQuarterID)
{
Double m_nAMOUNT = 0;
double nPercent = 0;
double nAnnualGrossPencentage = oBonusParm.PercentOfGross;
double nPerformancePercentage = oBonusParm.PerformanceBonusPercent;
nPercent = oBonusParm.Q1;
//switch(nQuarterID)
//{
// case 250:
// nPercent = oBonusParm.Q2;
// break;
// case 260:
// nPercent = oBonusParm.Q1;
// break;
//}
m_nAMOUNT = ((nGrossSalary * nAnnualGrossPencentage) / 100);
m_nAMOUNT = ((m_nAMOUNT * nPerformancePercentage) / 100);
m_nAMOUNT = m_nAMOUNT / 4;
m_nAMOUNT = ((m_nAMOUNT * nPercent) / 100);
//Previous
double PrevBonus = BonusProcess.GetKPIBonusAmountWithinYear(dCuttOfDate, oEmp.ID, oBonusParm.BonusID.Integer, oBonusParm.BonusID.Integer);
//double prevPercent=0;
//double prevAmount = 0;
//if(PrevBonus>0)
//{
// prevPercent = BonusProcess.GetKPIBonusAmountWithinYearPercent(dCuttOfDate, oEmp.ID, oBonusParm.BonusID.Integer, oBonusParm.BonusID.Integer);
// prevAmount = ((nGrossSalary * nAnnualGrossPencentage) / 100);
// prevAmount = ((prevAmount * nPerformancePercentage) / 100);
// prevAmount = prevAmount / 4;
// prevAmount = ((prevAmount * prevPercent) / 100);
//}
return (m_nAMOUNT ) - PrevBonus;
}
private double CalcluateCorporateBonus(BonusParameter oBonusParm, Employee oEmp, double nBasicSalary, double nGrossSalary, DateTime dCuttOfDate)
{
Double m_nAMOUNT = 0;
double nAnnualGrossPencentage = oBonusParm.PercentOfGross;
double nPerformancePercentage = oBonusParm.PerformanceBonusPercent;
m_nAMOUNT = ((nGrossSalary * nAnnualGrossPencentage) / 100);
m_nAMOUNT = ((m_nAMOUNT * nPerformancePercentage) / 100);
return m_nAMOUNT;
}
public void CalculateTax(BonusProcess oProcessedItems, ObjectsTemplate<Employee> oEmployees, Bonus oBonus)
{
if(SystemInformation.CurrentSysInfo.TaxParamID==null)throw new ServiceException("Current year Tax paramter setup not found.");
TaxParameter oparamter = TaxParameter.Get(SystemInformation.CurrentSysInfo.TaxParamID);
double nTaxAmount = 0;
UpdateprocessStatus("Calculating Tax");
UpdateProgressStatus(EnumProcessStatus.Start);
int nTotal = 0;
int nCount = 0;
nTotal = oProcessedItems.BonusProcessDetails.Count;
TaxCalculator oCalculator = new TaxCalculator();
try
{
foreach (BonusProcess.BonusProcessDetail item in oProcessedItems.BonusProcessDetails)
{
nCount++;
UpdateprocessStatus("Calculating Tax " + nCount.ToString() + "/" + nTotal.ToString());
UpdateProgressStatus(EnumProcessStatus.PerformStep);
oCalculator.TaxParameter = oparamter;
oCalculator.Employee = oEmployees.GetItem(item.EmployeeID);
if (item.ChangeBonusAmount > 0)
{
List<TaxRawItem> oTaxRowItems = new List<TaxRawItem>();
oTaxRowItems.Add(TaxRawItem.Create(oBonus.Name, item.ChangeBonusAmount, enumIncomeTaxItemType.Bonus, item.BonusID.Integer));
nTaxAmount = 0;
item.IncomeTaxcoll = oCalculator.CalculateBonus(oTaxRowItems, ref nTaxAmount);
item.TaxAmount = nTaxAmount;
item.ChangeTaxAmount = nTaxAmount;
}
}
}
catch(Exception exp) {
nCount = nCount;
throw new Exception(exp.Message);
}
UpdateProgressStatus(EnumProcessStatus.End);
}
public void UndoTax(BonusProcess oProcessedItems, ObjectsTemplate<Employee> oEmployees, Bonus oBonus)
{
if (SystemInformation.CurrentSysInfo.TaxParamID == null) throw new ServiceException("Current year Tax paramter setup not found.");
TaxParameter oparamter = TaxParameter.Get(SystemInformation.CurrentSysInfo.TaxParamID);
Employee oemp = null;
TaxCalculator oCalculator = new TaxCalculator();
foreach (BonusProcess.BonusProcessDetail item in oProcessedItems.BonusProcessDetails)
{
oCalculator.TaxParameter = oparamter;
oemp = oEmployees.GetItem(item.EmployeeID);
if (oemp == null)
{
oemp = Employee.Get(item.EmployeeID);
}
if(oemp==null) throw new ServiceException("Employee not found while undo tax process; employee No:" + item.Employee.EmployeeNo);
oCalculator.Employee = oemp;
List<TaxRawItem> oTaxRowItems = new List<TaxRawItem>();
oTaxRowItems.Add(TaxRawItem.Create(oBonus.Name, item.ChangeBonusAmount, enumIncomeTaxItemType.Bonus, item.BonusID.Integer));
item.IncomeTaxcoll = oCalculator.UndoBonus(oTaxRowItems, item.ChangeTaxAmount,oBonus.ID.Integer);
}
}
}
}