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 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; } /// /// /// /// /// /// /// /// public double CaculatedSalaryComponentAmount(BonusParameter parameter,Employee oEmp) { ObjectsTemplate _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 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 adParamsAll, ObjectsTemplate adParamEmpsAll, ObjectsTemplate grossDefinitions, DateTime dEffectDate, EmployeeGradeSalary oEmpGradeSal) { List adParams = null; List adParamEmps = null; ObjectsTemplate applicableParams = new ObjectsTemplate(); 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 adParamsAll, ObjectsTemplate adParamEmpsAll, ObjectsTemplate grossDefinitions, DateTime dEffectDate, EmployeeGradeSalary oEmpGradeSal) { List adParams = null; List adParamEmps = null; ObjectsTemplate applicableParams = new ObjectsTemplate(); 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 adParamsAll, ObjectsTemplate adParamEmpsAll, ObjectsTemplate grossDefinitions, DateTime dEffectDate) { List adParams = null; List adParamEmps = null; ObjectsTemplate applicableParams = new ObjectsTemplate(); 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 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.GetProcess(); ObjectsTemplate _bonusProcessTemp = new ObjectsTemplate(); List oSetupManagerTranTypes = SetupDetail.GetTypes(EnumParameterSetup.Bonus); ObjectsTemplate oSetupDetails = SetupDetail.GetParameters(EnumParameterSetup.Bonus); bool CheckOvertheYearCal = ConfigurationManager.GetBoolValue("bonus", "overtheyearcalculation", EnumConfigurationType.Logic); ObjectsTemplate paramAll = BonusParameter.Get(EnumStatus.Active); int nTotal = oEmployees.Count; BonusProcess oProssBonus = new BonusProcess(); oProssBonus.BonusProcessDetails = new ObjectsTemplate(); double nBasicSalary = 0; double nGrossSalary = 0; //ObjectsTemplate adParams = ADParameter.Get(EnumStatus.Active); //ObjectsTemplate adParamEmps = ADParameterEmployee.Get(EnumStatus.Active); ObjectsTemplate grossDefinitions = GrossDefination.Get(); List 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 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 oParams = BonusParameter.ApplicableParameters3(oEmp, oBonus.ID, oSetupManagerTranTypes, oSetupDetails, paramAll); ObjectsTemplate adParams = ADParameter.Get(oEmp.GradeID, EnumEntitleType.Grade, EnumAllowOrDeduct.Allowance); ObjectsTemplate 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 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(); 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 oBonusProcesses = new ObjectsTemplate(); //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 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 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 oTaxRowItems = new List(); 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 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 oTaxRowItems = new List(); oTaxRowItems.Add(TaxRawItem.Create(oBonus.Name, item.ChangeBonusAmount, enumIncomeTaxItemType.Bonus, item.BonusID.Integer)); item.IncomeTaxcoll = oCalculator.UndoBonus(oTaxRowItems, item.ChangeTaxAmount,oBonus.ID.Integer); } } } }