using System; using Ease.Core.Model; using Ease.Core.DataAccess; using HRM.BO; using Ease.Core.Utility; using System.Collections.Generic; using System.Linq; using System.Data; using System.Reflection.Metadata; using System.Runtime.CompilerServices; using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal; namespace HRM.DA { public delegate void ProcessStatus(string processStatus); public delegate void ProgressStatus(EnumProcessStatus status); public delegate void ErrorMessage(String error); public enum EnumProcessStatus { Start = 1, PerformStep = 2, End = 3 } public class SalaryCalculator : SalaryException { #region Define Class Veriable private List _employees; private List _allowdeducitons; private List _processItems; private List _salaryMonthlys; private List _processStatuses; // private List _PrvMonthsalary; private List _PrvMonthsalaryItems; private List _salaryHistories; private List _adParameters; public DateTime _processMonth; public double _euroRate = 0; private List _attnHours; public event ProcessStatus ProcessStatus; public event ProgressStatus ProgressStatus; public List _greades; public List _attnBenifits; // public List _empWorkPlans; public List _attnProcess; List _bonusdetails; private List _attendanceForGrossFraction; private string _maternityCode; public string _lwopCode; private Dictionary _empIDsMLPartial = new Dictionary(); private Dictionary _empIDsLWOP = new Dictionary(); private List _empIDsforMLRemoval = new List(); bool isMaternityOutsidePayroll; #endregion Define Class Veriable public List SalaryMonthlies { get { return _salaryMonthlys; } } public SalaryCalculator() { _processItems = new ProcessItemService().Get(); } public List ErrorList { get { return _processStatuses; } } public List Adparameter { get { return _adParameters; } } private void UpdateprocessStatus(string statusString) { if (ProcessStatus != null) ProcessStatus(statusString); } private void UpdateProgressStatus(EnumProcessStatus status) { if (ProgressStatus != null) ProgressStatus(status); } public SystemInformation systemInformation { get; set; } public PayrollType payrollType { get; set; } public List Employees { get { return _employees; } } public int PayrollTypeID { get; set; } public void Process(List employees, DateTime processMonth, int payrolltypeid, double euroRate) { //SalaryException oSException = new SalaryException(); this.systemInformation = new SystemInformationService().Get(); this.PayrollTypeID = payrolltypeid; this.payrollType = new PayrollTypeService().Get(payrolltypeid); this.PayrollTypeID = payrolltypeid; _employees = employees; _processMonth = processMonth; _euroRate = euroRate; UpdateprocessStatus("Collecting Employee basic information...."); this.Initialize(); this.AddEmployeeToProcess(); if (_processStatuses.Count > 0) return; UpdateprocessStatus("Calculating basic Salary...."); this.BasicSalary(); UpdateprocessStatus("Calculating benifits and deduction...."); this.AllowanceDeduction(); UpdateprocessStatus("Calculating OverTime...."); this.OverTimeProcess(); UpdateprocessStatus("Calculating Bonus...."); this.CalculateBonus(); UpdateprocessStatus("Calculating Salary deduct item(unauthorized leave)...."); this.UnAuthorizeLeave(); UpdateprocessStatus("Calculating PF & CPF...."); this.PF(); // this.OverTimeArrearProcess(); needed later //UpdateprocessStatus("Calculating Employees Income tax...."); UpdateprocessStatus("Calculating Income Tax"); this.Tax(); UpdateprocessStatus("Calculating Cost-Center"); this.PrepareCostcenterData(); UpdateprocessStatus("Calculating Loan Installment"); this.LoanProcess(); UpdateprocessStatus("Calculating Net Income"); //UpdateprocessStatus("Calculating Attendance Days"); this.AttendanceDayProcess(); UpdateprocessStatus("Calculating Leave Days"); this.LeaveDayProcess(); UpdateprocessStatus("Calculating Salary Exception"); this.SalaryExceptionCalculation(this); UpdateprocessStatus(""); this.NetIncome(); //this.LeavePrepare(oSException.GetEmpLeaveStatus()); } public void ProcessLTA(List employees, DateTime processMonth, int payrolltypeid) { //SalaryException oSException = new SalaryException(); _employees = employees; _processMonth = processMonth; UpdateprocessStatus("Collecting Employee basic information...."); this.Initialize(); this.AddEmployeeToProcess(); if (_processStatuses.Count > 0) return; UpdateprocessStatus("Calculating basic Salary...."); this.BasicSalary(); UpdateprocessStatus("Calculating benifits and deduction...."); this.AllowanceDeduction(); UpdateprocessStatus("Calculating OverTime...."); this.OverTimeProcess(); UpdateprocessStatus("Calculating PF & CPF...."); this.PF(); this.OverTimeArrearProcess(); } private void Initialize() { _processStatuses = new List(); _salaryMonthlys = new List(); //_PrvMonthsalary = new SalaryMonthlyService().Get( // GlobalFunctions.LastDateOfMonth(_processMonth.AddMonths(-1)), this.PayrollTypeID); List itemCodes = new List(); itemCodes.Add(EnumSalaryItemCode.Basic_Salary); itemCodes.Add(EnumSalaryItemCode.PF_Contribution); itemCodes.Add(EnumSalaryItemCode.Inc_Tax_Deduction); _PrvMonthsalaryItems = new SalaryMonthlyService().getbyItemCode( itemCodes, this.PayrollTypeID, GlobalFunctions.LastDateOfMonth(_processMonth.AddMonths(-1))); this.CollectMaternityLeaveData(); //this._salaryHistories = new SalaryMonthlyService().GetSalaryHistories(this.PayrollTypeID, // Employee.getEmpID(this.Employees), GlobalFunctions.FirstDateOfMonth(this._processMonth.AddMonths(-12)), // GlobalFunctions.LastDateOfMonth(this._processMonth.AddMonths(-1))); } private bool ProcessStartValidation() { return false; } private void AddEmployeeToProcess() { UpdateProgressStatus(EnumProcessStatus.Start); List empCostCenters = new EmployeeCostCenterService().Get(); List categories = new CategoryService().Get(EnumStatus.Regardless, this.PayrollTypeID); List gradFathers = new List(); //BATBGrandFatherTaging.Get(); _greades = new GradeService().Get(EnumStatus.Regardless, this.PayrollTypeID); _attnBenifits = new List(); //new AttnMonthlyBenefit().Get(_processMonth); bool bfixedAmount = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "costcenter", "manadatoryinsalary"); foreach (Employee employee in _employees) { UpdateProgressStatus(EnumProcessStatus.PerformStep); this.UpdateprocessStatus(" Collecting information for the employee " + employee.Name + " ( " + employee.EmployeeNo + ")"); if (_empIDsforMLRemoval != null && _empIDsforMLRemoval.Contains(employee.ID)) // || _empIDsforLWOPRemoval.Contains(employee.ID.Integer)) { continue; } SalaryMonthly salary = new SalaryMonthly(); salary.EmployeeID = employee.ID; salary.CategoryID = employee.CategoryID; if (employee.CategoryID == null) { AddProcessStatus(employee, "Category not yet assingned"); } else { var oc = categories.FirstOrDefault(x => x.ID == employee.CategoryID); if(oc != null) salary.Category = categories.FirstOrDefault(x => x.ID == employee.CategoryID); else AddProcessStatus(employee, "Categoryid not not found in the list"); } salary.Gender = employee.Gender; salary.SalaryMonth = _processMonth; salary.EuroRate = _euroRate; if (employee.GradeID == null) AddProcessStatus(employee, "grade not yet assingned"); else salary.GradeID = (int)employee.GradeID; if (employee.DepartmentID == null) AddProcessStatus(employee, "Department not yet assingned"); else salary.DepartmentID = (int)employee.DepartmentID; if (employee.DesignationID == null) AddProcessStatus(employee, "Designation not yet assingned"); else salary.DesignationID = (int)employee.DesignationID; if (employee.LocationID == null) AddProcessStatus(employee, "Loacation not yet assingned"); else salary.LocationID = (int)employee.LocationID; //salary.DesignationID = (int)employee.DesignationID; salary.DesignationText = employee.DescriptionText; if (employee.PaymentMode == EnumPaymentMode.BankTransfer) { if (employee.BranchID == null) AddProcessStatus(employee, "Employee payment mode is diclared" + " to bank transfer, but no bank/account information found"); else { salary.BranchID = (int)employee.BranchID; salary.AccountNo = employee.AccountNo; } } salary.ThisMonthBasic = employee.BasicSalary; salary.ThisMonthGross = employee.GrossSalary; salary.PayrollTypeID = employee.PayrollTypeID; salary.ReligionID = employee.ReligionID; salary.Employee = employee; salary.IsConfirmed = employee.IsConfirmed; if (employee.EndOfContractDate != null) if (employee.EndOfContractDate >= GlobalFunctions.FirstDateOfMonth(_processMonth) && employee.EndOfContractDate <= GlobalFunctions.LastDateOfMonth(_processMonth)) { if (employee.Status == EnumEmployeeStatus.Live && employee.MonthStatusUpdate == EnumEmployeeStatus.Live) AddProcessStatus(employee, "Employee end_of_contact_date defined but not yet discontinued from discontinue module." + " "); } if (bfixedAmount == true) { List empinvolments = new EmployeeCostCenterService().Get(empCostCenters, salary.EmployeeID); if (empinvolments == null || empinvolments.Count == 0) AddProcessStatus(employee, "Cost-Center not yet assingned"); } salary.salaryWithHeld = employee.IsSalaryWithHeld; // salary.Employee.GrandFather = gradFathers.Find(delegate (BATBGrandFatherTaging detail) { return (detail.EmployeeID == employee.ID.Integer); }); _salaryMonthlys.Add(salary); } UpdateProgressStatus(EnumProcessStatus.End); } private void AddProcessStatus(Employee employee, string remarks) { SalaryProcessStatus status = new SalaryProcessStatus(); status.EmployeeNo = employee.EmployeeNo; status.Name = employee.Name; status.Remarks = remarks; _processStatuses.Add(status); } private void NetIncome() { string sPosItems = "Positive Items:"; string sNegItems = "Negative Items:"; UpdateProgressStatus(EnumProcessStatus.Start); foreach (SalaryMonthly salary in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); double netAmount = 0; sPosItems = "Positive Items:"; sNegItems = "Negative Items:"; foreach (SalaryMonthlyDetail detail in salary.Details) { string sName = detail.Description; if (sName.Length > 4) sName = sName.Substring(0, 4); if (detail.itemGroupCode == EnumSalaryGroup.Gross || detail.itemGroupCode == EnumSalaryGroup.Arrear) { netAmount = netAmount + detail.ChangedAmount; sPosItems = sPosItems + sName + ":" + detail.ChangedAmount.ToString() + ", "; } else if (detail.itemGroupCode == EnumSalaryGroup.Deductions || detail.itemGroupCode == EnumSalaryGroup.UnauthLeave) { netAmount = netAmount - detail.ChangedAmount; sNegItems = sNegItems + sName + ":" + detail.ChangedAmount.ToString() + ", "; } } this.AddDetail(salary, EnumSalaryGroup.OtherItem, EnumSalaryItemCode.Net_Payable, (int)EnumSalaryItemCode.Net_Payable, 0, "Net Amount", GlobalFunctions.Round(netAmount)); if (netAmount <0) { sPosItems = sPosItems.Substring(0, sPosItems.Length - 2); sNegItems = sNegItems.Substring(0, sNegItems.Length - 2); this.AddProcessStatus(salary.Employee, "Net amount can't be less than zero. Components:" + sPosItems + " " + sNegItems); } if (netAmount == 0) { bool bfixedAmount = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "salary", "allownetincomezero"); if (bfixedAmount == false) { sPosItems = sPosItems.Substring(0, sPosItems.Length - 2); sNegItems = sNegItems.Substring(0, sNegItems.Length - 2); this.AddProcessStatus(salary.Employee, "Net amount can't be Zero. Components:" + sPosItems + " " + sNegItems); } } } UpdateProgressStatus(EnumProcessStatus.End); } public SalaryMonthlyDetail AddDetail(SalaryMonthly salarymonthly, EnumSalaryGroup group, EnumSalaryItemCode itemcode, int itemId , int? supportId, string description, double nAmount) { SalaryMonthlyDetail detail = new SalaryMonthlyDetail(); ProcessItem pitem = _processItems.FirstOrDefault(x=>x.ItemCode == (int)itemcode); if (pitem == null) { this.AddProcessStatus(salarymonthly.Employee, "Salary process item code not found in the process" + " collection; Item Code:" + itemcode.ToString()); return null; } detail = salarymonthly.Details.FirstOrDefault(x => x.ItemID == itemId && x.itemGroupCode == group && x.ItemCode == itemcode); if (detail == null) { detail = new SalaryMonthlyDetail(); detail.ItemID = itemId; detail.itemGroupCode = group; detail.ItemCode = itemcode; detail.SupportID = (supportId); detail.Position = GetMaxPostion(salarymonthly, group); detail.Description = description.Length > 0 ? description : pitem.UserDescription; detail.CalculatedAmount = nAmount; detail.ChangedAmount = detail.CalculatedAmount; salarymonthly.Details.Add(detail); } else { detail.CalculatedAmount = detail.CalculatedAmount + nAmount; detail.ChangedAmount = detail.CalculatedAmount; } return detail; } public int GetMaxPostion(SalaryMonthly osalary, EnumSalaryGroup group) { int maxPos = 0; foreach (SalaryMonthlyDetail item in osalary.Details) { //if(item.itemGroupCode == group) //{ if (item.Position > maxPos) { maxPos = item.Position; //} } } maxPos = maxPos + 1; return maxPos; } private void CalculateWagesBasicSalary(SalaryMonthly salary) { if (_attnHours == null) { /// _attnHours = new AttnMonthlyBenefitService.Get(salary.SalaryMonth); } if (salary.Category.WagesType == EnumWagesType.Hourly) { double amount = 0; double Hours = 208; AttnMonthlyBenefit basicsHours = _attnHours.Find(delegate (AttnMonthlyBenefit detail) { return (detail.ItemType == enumPayrollComponentType.Ordinary_Hour && detail.EmployeeID == salary.EmployeeID && detail.ItemID == (int)enumPayrollComponentType.Ordinary_Hour); }); if (basicsHours != null) Hours = Hours - basicsHours.Total; //AttnMonthlyBenefit ExtraHour = _attnHours.Find(delegate (AttnMonthlyBenefit detail) { return (detail.ItemType == enumPayrollComponentType.Ordinary_Hour_Extra && detail.EmployeeID == salary.EmployeeID && detail.ItemID == (int)enumPayrollComponentType.Ordinary_Hour_Extra); }); //if (ExtraHour != null && ExtraHour.Total > 0) // Hours = Hours + ExtraHour.Total; // amount = Hours * GlobalFunctions.ConvertToHourlyRate(salary.ThisMonthBasic); this.AddDetail(salary, EnumSalaryGroup.Gross, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, 0, "Ordinary Amount", GlobalFunctions.Round(amount)); this.AddDetail(salary, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, 0, "Ordinary Hours", Hours); } } private void BasicSalary() { UpdateProgressStatus(EnumProcessStatus.Start); #region Calculate Normal Salary List gradeSalaryItems = new EmployeeGradeSalaryService().GetCurrMonthSalaryItems( this._processMonth, this.PayrollTypeID); double basicSalary = 0; SalaryMonthlyDetail basicDetail = null; foreach (SalaryMonthly salary in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); salary.GradeSalaries = gradeSalaryItems.FindAll(x => x.EmployeeID == salary.EmployeeID); if (salary.GradeSalaries.Count == 0) { this.AddProcessStatus(salary.Employee, "Grade/Salary not found in the system"); continue; } EmployeeGradeSalary.PrepareDataForCurrentSalary(this._processMonth, salary.Employee, salary.GradeSalaries); if (_empIDsMLPartial != null && _empIDsMLPartial.ContainsKey(salary.EmployeeID)) { EmployeeGradeSalary.PrepareDataForMaternityLeaveReturnCurrentSalary(salary.Employee, salary.GradeSalaries, _empIDsMLPartial[salary.EmployeeID].Date.AddDays(1), _processMonth); } basicSalary = 0; //if (salary.Category.WagesType != EnumWagesType.Monthly) //{ // this.CalculateWagesBasicSalary(salary); // continue; //} if (salary.GradeSalaries.Count > 0) { salary.ThisMonthBasic = salary.GradeSalaries[salary.GradeSalaries.Count - 1].BasicSalary; salary.ThisMonthBasic = GlobalFunctions.Round(salary.ThisMonthBasic); salary.ThisMonthGross = salary.GradeSalaries[salary.GradeSalaries.Count - 1].GrossSalary; salary.ThisMonthGross = GlobalFunctions.Round(salary.ThisMonthGross); } foreach (EmployeeGradeSalary item in salary.GradeSalaries) { item.BasicSalary = item.BasicSalary * item.FractionofFromTo; item.BasicSalary = GlobalFunctions.Round(item.BasicSalary); item.GrossSalary = item.GrossSalary * item.FractionofFromTo; item.GrossSalary = GlobalFunctions.Round(item.GrossSalary); basicSalary = basicSalary + item.BasicSalary; } basicDetail = this.AddDetail(salary, EnumSalaryGroup.Gross, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, 0, "Basic", GlobalFunctions.Round(basicSalary)); //} //else //{ // basicDetail = this.AddDetail(salary, EnumSalaryGroup.Gross, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, 0, "Ordinary Amount", PayrollPayrollGlobalFunctions.Round(basicSalary)); //} } #endregion Calculate Normal Salary #region calculate arrear amount double arrearAmount = 0; List arrearItems = new EmployeeGradeSalaryService().GetArrearItems(this.PayrollTypeID); foreach (SalaryMonthly salary in _salaryMonthlys) { arrearAmount = 0; salary.ArrearGradeSalaries = arrearItems.FindAll(x => x.EmployeeID == salary.EmployeeID); foreach (EmployeeGradeSalary arrearItem in salary.ArrearGradeSalaries) { arrearItem.BasicSalary = arrearItem.BasicSalary * GlobalFunctions.GetFraction(arrearItem.EffectDate, (DateTime)arrearItem.TillDate); arrearItem.BasicSalary = GlobalFunctions.Round(arrearItem.BasicSalary); arrearItem.GrossSalary = arrearItem.GrossSalary * GlobalFunctions.GetFraction(arrearItem.EffectDate, (DateTime)arrearItem.TillDate); arrearItem.GrossSalary = GlobalFunctions.Round(arrearItem.GrossSalary); arrearItem.FractionofFromTo = GlobalFunctions.GetFraction(arrearItem.EffectDate, (DateTime)arrearItem.TillDate); arrearAmount = (arrearAmount + arrearItem.BasicSalary) - new SalaryMonthlyService().GetAmountOnRange(salary.Employee, arrearItem.EffectDate, (DateTime)arrearItem.TillDate, EnumSalaryGroup.Gross, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, arrearItem, null); arrearAmount = GlobalFunctions.Round(arrearAmount); } if (salary.ArrearGradeSalaries.Count > 0) { // Arrear Paid not needed //if (salary.Category.WagesType == EnumWagesType.Monthly) //{ // DateTime arrearPaidFrom = salary.ArrearGradeSalaries[0].EffectDate; // salary.ArrearPaidGradeSalaries = new EmployeeGradeSalaryService().GetArrearPaidItems(salary.EmployeeID, arrearPaidFrom, this.PayrollTypeID); // if (salary.ArrearPaidGradeSalaries.Count > 0) // { // if (salary.ArrearPaidGradeSalaries[0].EffectDate < arrearPaidFrom) // salary.ArrearPaidGradeSalaries[0].EffectDate = arrearPaidFrom; // } // foreach (EmployeeGradeSalary paidarrearItem in salary.ArrearPaidGradeSalaries) // { // paidarrearItem.BasicSalary = paidarrearItem.BasicSalary * GlobalFunctions.GetFraction(paidarrearItem.EffectDate, (DateTime)paidarrearItem.TillDate); // paidarrearItem.BasicSalary = GlobalFunctions.Round(paidarrearItem.BasicSalary); // paidarrearItem.GrossSalary = paidarrearItem.GrossSalary * GlobalFunctions.GetFraction(paidarrearItem.EffectDate, (DateTime)paidarrearItem.TillDate); // paidarrearItem.GrossSalary = GlobalFunctions.Round(paidarrearItem.GrossSalary); // paidarrearItem.FractionofFromTo = GlobalFunctions.GetFraction(paidarrearItem.EffectDate, (DateTime)paidarrearItem.TillDate); // //arrearAmount = arrearAmount - (paidarrearItem.BasicSalary - salary.GetAmountOnRange(salary.Employee, paidarrearItem.EffectDate, (DateTime)paidarrearItem.TillDate, EnumSalaryGroup.Gross, // // EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary)); // arrearAmount = GlobalFunctions.Round(arrearAmount); // } //} if (arrearAmount != 0) { SalaryMonthlyDetail detail = null; detail = this.AddDetail(salary, EnumSalaryGroup.Arrear, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, 0, "Basic", GlobalFunctions.Round(arrearAmount)); if (detail != null && basicDetail != null) { detail.Position = basicDetail.Position; } } } } #endregion calculate arrear amount UpdateProgressStatus(EnumProcessStatus.End); } private void PF() { UpdateProgressStatus(EnumProcessStatus.Start); bool bEchoTexException = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "salary", "echotexexception"); bool earnedBasic = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "pf", "earnedbasic"); double pfPercent = (this.systemInformation.pFContriCompany / 100); //List oPfExceptions = PFException.Get(); foreach (SalaryMonthly salary in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); SalaryMonthlyDetail pfDetail = null; if (salary.Employee.PFMemberType != EnumPFMembershipType.Live) continue; // SalaryMonthly prvSalary = _PrvMonthsalary.FirstOrDefault(x => x.EmployeeID == salary.EmployeeID); var basicitem = _PrvMonthsalaryItems.FirstOrDefault(x => x.itemCode == EnumSalaryItemCode.Basic_Salary && x.empid == salary.EmployeeID); bool RcvLastMonthSalary = false; if (basicitem != null) RcvLastMonthSalary = true; double arrearPF = 0; if (earnedBasic == true) { if (RcvLastMonthSalary == true) { //SalaryMonthlyDetail prvPF = prvSalary.Details.Find(delegate (SalaryMonthlyDetail detail) //{ // return (detail.ItemCode == EnumSalaryItemCode.PF_Contribution // && detail.itemGroupCode == EnumSalaryGroup.Deductions); //}); var prvPF = _PrvMonthsalaryItems.FirstOrDefault(x => x.itemCode == EnumSalaryItemCode.PF_Contribution && x.empid == salary.EmployeeID); if (salary.Employee.ConfirDate != null && salary.Employee.ConfirDate < GlobalFunctions.FirstDateOfMonth(_processMonth) && RcvLastMonthSalary == true && prvPF == null) // if pf continue with previous month salary { DateTime? tepConfirm = salary.Employee.ConfirDate; while (GlobalFunctions.LastDateOfMonth((DateTime)tepConfirm) <= this.payrollType.LastPayProcessDate) { EmployeeGradeSalary gradeSal = new EmployeeGradeSalaryService().GetBasicOnDateBAT(salary.EmployeeID, (DateTime)tepConfirm); if (gradeSal == null) { AddProcessStatus(salary.Employee, " Employee previous salary not found during PF arrear calculation"); break; } double fractionate = 0; if (tepConfirm == GlobalFunctions.FirstDateOfMonth((DateTime)tepConfirm)) fractionate = 1; if (tepConfirm == GlobalFunctions.LastDateOfMonth((DateTime)tepConfirm)) fractionate = 30 / 29; else fractionate = GlobalFunctions.GetFractinalOfMonth((DateTime)tepConfirm); arrearPF = arrearPF + ((gradeSal.BasicSalary * fractionate) * pfPercent); tepConfirm = GlobalFunctions.FirstDateOfMonth(((DateTime)tepConfirm).AddMonths(1)); } } } SalaryMonthlyDetail basic = salary.Details.Find(delegate (SalaryMonthlyDetail detail) { return (detail.ItemCode == EnumSalaryItemCode.Basic_Salary && detail.itemGroupCode == EnumSalaryGroup.Gross); }); if (basic != null) { pfDetail = this.AddDetail(salary, EnumSalaryGroup.Deductions, EnumSalaryItemCode.PF_Contribution, (int)EnumSalaryItemCode.PF_Contribution, 0, "PF", GlobalFunctions.Round(basic.CalculatedAmount * pfPercent)); } basic = salary.Details.Find(delegate (SalaryMonthlyDetail detail) { return (detail.ItemCode == EnumSalaryItemCode.Basic_Salary && detail.itemGroupCode == EnumSalaryGroup.Arrear); }); if (basic != null) { pfDetail.CalculatedAmount = pfDetail.CalculatedAmount + GlobalFunctions.Round(basic.CalculatedAmount * pfPercent); } basic = salary.Details.Find(delegate (SalaryMonthlyDetail detail) { return (detail.ItemCode == EnumSalaryItemCode.Basic_Salary && detail.itemGroupCode == EnumSalaryGroup.UnauthLeave); }); if (basic != null) { pfDetail.CalculatedAmount = pfDetail.CalculatedAmount - GlobalFunctions.Round(basic.CalculatedAmount * pfPercent); } if (pfDetail != null) { if (salary.Employee.ConfirDate != null && GlobalFunctions.LastDateOfMonth((DateTime)salary.Employee.ConfirDate) == _processMonth) { if ((DateTime)salary.Employee.ConfirDate != salary.Employee.JoiningDate) { pfDetail.CalculatedAmount = GlobalFunctions.Round(pfDetail.CalculatedAmount * ((double)(31 - ((DateTime)salary.Employee.ConfirDate).Day) / (double)30)); } } pfDetail.CalculatedAmount = pfDetail.CalculatedAmount + GlobalFunctions.Round(arrearPF); pfDetail.ChangedAmount = pfDetail.CalculatedAmount; } } else { double months = 1; if (bEchoTexException == false) { salaryHistory prvPF = null; if (RcvLastMonthSalary == true) { prvPF = _PrvMonthsalaryItems.FirstOrDefault(x => x.itemCode == EnumSalaryItemCode.PF_Contribution && x.empid == salary.EmployeeID); } if (RcvLastMonthSalary == true) { if (prvPF == null) months = Global.DateFunctions.DateDiff("m", (DateTime)salary.Employee.ConfirDate, _processMonth) + 1; else { if (salary.ArrearGradeSalaries.Count > 0) { pfDetail = this.AddDetail(salary, EnumSalaryGroup.Deductions, EnumSalaryItemCode.PF_Contribution, (int)EnumSalaryItemCode.PF_Contribution, 0, "PF", GlobalFunctions.Round(salary.GetGrossAmount(EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary) * pfPercent)); continue; } } } else if ((Global.DateFunctions.DateDiff("m", (DateTime)salary.Employee.JoiningDate, _processMonth) + 1) <= 2) // joining in last month { months = Global.DateFunctions.DateDiff("m", (DateTime)salary.Employee.JoiningDate, _processMonth) + 1; } } pfDetail = this.AddDetail(salary, EnumSalaryGroup.Deductions, EnumSalaryItemCode.PF_Contribution, (int)EnumSalaryItemCode.PF_Contribution, 0, "PF", GlobalFunctions.Round(salary.ThisMonthBasic * pfPercent * months)); } } UpdateProgressStatus(EnumProcessStatus.End); } private void AllowanceDeduction() { UpdateProgressStatus(EnumProcessStatus.Start); _adParameters = new ADParameterService().GetWithDetail(EnumStatus.Regardless, this.PayrollTypeID); if (_adParameters == null || _adParameters.Count == 0) { return; } _allowdeducitons = new AllowanceDeductionService().Get(EnumStatus.Regardless, this.PayrollTypeID); List indvAllowances = new ADParameterEmployeeService().Get( GlobalFunctions.FirstDateOfMonth(_processMonth), GlobalFunctions.LastDateOfMonth(_processMonth), this.PayrollTypeID); double totalPresentDays = 0; foreach (SalaryMonthly salary in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); new ADParameterService().ApplicableParameters(salary.Employee, salary, _adParameters); this.GradeDefinedAllowDeduct(salary, salary.GradeSalaries, EnumSalaryGroup.Gross, indvAllowances, EnumSide.Add); this.GradeDefinedAllowDeduct(salary, salary.ArrearGradeSalaries, EnumSalaryGroup.Arrear, indvAllowances, EnumSide.Add); // this.GradeDefinedAllowDeduct(salary, salary.ArrearPaidGradeSalaries, EnumSalaryGroup.Arrear, indvAllowances, EnumSide.Deduct); leter we can introduce this.IndividualAllowDeduct(salary, indvAllowances, totalPresentDays); } } private void IndividualAllowDeduct(SalaryMonthly salary, List indvAllowances, double toTalPresentDays) { double amount = 0; EnumSalaryGroup groupCode = EnumSalaryGroup.Gross; #region Individual Allowance List items = indvAllowances.FindAll(delegate (ADParameterEmployee item) { return item.EmployeeID == salary.Employee.ID && item.ADEmpType == EnumADEmpType.AppliedToIndividual; }); foreach (ADParameterEmployee item in items) { item.AllowDeduct = _allowdeducitons.FirstOrDefault(x => x.ID == item.AllowDeductID); amount = 0; ADParameter parameter = _adParameters.FirstOrDefault(x => x.ID == item.ADParameterID); parameter.AllowanceDeduction = _allowdeducitons.FirstOrDefault(x => x.ID == item.AllowDeductID); if (parameter == null) continue; amount = new ADParameterService().GetIndividualAmount(salary.Employee, _processMonth, item, salary.Employee.GrossSalary, salary.GetGrossAmount(EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary), parameter, this.payrollType.NextPayProcessDate); EnumSalaryItemCode itemCode = EnumSalaryItemCode.Allowance; groupCode = EnumSalaryGroup.Gross; if (parameter.AllowOrDeductType == EnumAllowOrDeduct.Deduction) { itemCode = EnumSalaryItemCode.Deduction; groupCode = EnumSalaryGroup.Deductions; } if (item.Arreartype == EnumArrearType.ToCalculate) groupCode = EnumSalaryGroup.Arrear; if (groupCode == EnumSalaryGroup.Arrear) { amount = amount - new SalaryMonthlyService().GetUnAuthorizeAmount(amount, salary.Employee, item.FormDate, (DateTime)item.TillDate, itemCode, parameter.AllowDeductID); EnumSalaryGroup arrgCode = (parameter.AllowanceDeduction.AllowOrDeductType == EnumAllowOrDeduct.Allowance) ? EnumSalaryGroup.Gross : EnumSalaryGroup.Deductions; amount = amount - new SalaryMonthlyService().GetAmountOnRange(salary.Employee, item.FormDate, (DateTime)item.TillDate, arrgCode, itemCode, parameter.AllowDeductID, parameter.ID, null, parameter); if (amount == 0) continue; } SalaryMonthlyDetail detail = salary.Details.FirstOrDefault(x => x.itemGroupCode == groupCode && x.ItemCode == itemCode && x.ItemID == parameter.AllowDeductID); if (detail == null) { detail = this.AddDetail(salary, groupCode, itemCode, parameter.AllowDeductID, parameter.ID, parameter.AllowanceDeduction.Name, GlobalFunctions.Round(amount)); } else { detail.CalculatedAmount = detail.CalculatedAmount + amount; detail.CalculatedAmount = GlobalFunctions.Round(detail.CalculatedAmount); detail.ChangedAmount = detail.CalculatedAmount; detail.SupportID = parameter.ID; } if (detail != null) detail.Position = item.AllowDeduct.Sequence + 1; } #endregion Individual Allowance } private void GradeDefinedAllowDeduct(SalaryMonthly salary, List gradeSalaries, EnumSalaryGroup gCode, List indvAllowances, EnumSide side) { double amount = 0; EnumSalaryGroup GroupCode = gCode; foreach (EmployeeGradeSalary empGradeSalary in gradeSalaries) { foreach (ADParameter parameter in empGradeSalary.ADParameters) { GroupCode = gCode; parameter.AllowanceDeduction = _allowdeducitons.FirstOrDefault(x => x.ID == parameter.AllowDeductID); if (parameter.AllowanceDeduction.AllowOrDeductType == EnumAllowOrDeduct.Deduction && GroupCode == EnumSalaryGroup.Gross) GroupCode = EnumSalaryGroup.Deductions; EnumSalaryItemCode itemCode = (parameter.AllowOrDeductType == EnumAllowOrDeduct.Allowance) ? EnumSalaryItemCode.Allowance : EnumSalaryItemCode.Deduction; amount = 0; if (parameter.EntitleType == EnumEntitleType.Grade) { if (salary.Category.WagesType == EnumWagesType.Monthly) { amount = new ADParameterService().GetGradeDefinedAmount(salary.Employee, empGradeSalary.BasicSalary, empGradeSalary.GrossSalary, empGradeSalary, parameter); // for echotex if (parameter.AllowanceDeduction.Code == "023" && parameter.AllowanceDeduction.Name == "Night shift allowance" && amount >0) { amount = parameter.FlatAmount; } } } else continue; if (GroupCode == EnumSalaryGroup.Arrear && parameter.AllowanceDeduction.AllowOrDeductType == EnumAllowOrDeduct.Deduction) continue;// system will not calculate Deduction Arrear if (GroupCode == EnumSalaryGroup.Arrear && salary.Category.WagesType == EnumWagesType.Monthly) { amount = amount - new SalaryMonthlyService().GetUnAuthorizeAmount(amount, salary.Employee, empGradeSalary.EffectDate, (DateTime)empGradeSalary.TillDate, itemCode, parameter.AllowDeductID); EnumSalaryGroup arrgCode = (parameter.AllowanceDeduction.AllowOrDeductType == EnumAllowOrDeduct.Allowance) ? EnumSalaryGroup.Gross : EnumSalaryGroup.Deductions; amount = amount - new SalaryMonthlyService().GetAmountOnRange(salary.Employee, empGradeSalary.EffectDate, (DateTime)empGradeSalary.TillDate, arrgCode, itemCode, parameter.AllowDeductID, parameter.ID, empGradeSalary, parameter); if (amount == 0) continue; } if (GroupCode == EnumSalaryGroup.Arrear && side == EnumSide.Deduct) amount = -amount; // never happen SalaryMonthlyDetail detail = salary.Details.FirstOrDefault(x => x.itemGroupCode == GroupCode && x.ItemCode == itemCode && x.ItemID == parameter.AllowDeductID); if (detail == null) { detail = this.AddDetail(salary, GroupCode, itemCode, parameter.AllowDeductID, parameter.ID, parameter.AllowanceDeduction.Name, GlobalFunctions.Round(amount)); } else { detail.CalculatedAmount = detail.CalculatedAmount + amount; detail.CalculatedAmount = GlobalFunctions.Round(detail.CalculatedAmount); detail.ChangedAmount = detail.CalculatedAmount; detail.SupportID = parameter.ID; } if (detail != null) detail.Position = parameter.AllowanceDeduction.Sequence + 1; } } } private void OverTimeProcess() { UpdateProgressStatus(EnumProcessStatus.Start); bool otDisburseSalary = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "overtime", "disbursefromsalary"); if (otDisburseSalary == false) return; TermParameter ob = new TermParameter(); List otProcess = new OTProcessService().Get(this._processMonth); if (otProcess == null || otProcess.Count == 0) return; List trms = new TermService().Get(EnumStatus.Regardless, this.PayrollTypeID); foreach (SalaryMonthly sMonthly in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); List empOTProcess = otProcess.FindAll(x => x.EmployeeID == sMonthly.EmployeeID); if (empOTProcess != null) { foreach (OTProcess process in empOTProcess) { process.TermObj = trms.FirstOrDefault(x => x.ID == process.TermID); if (process.TermObj != null) { this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Over_Time_Hours, process.TermID, process.TermParameterID, process.TermObj.Name + " hour", process.TotalHour); this.AddDetail(sMonthly, EnumSalaryGroup.Gross, EnumSalaryItemCode.Over_Time_Amount, process.TermID, process.TermParameterID, process.TermObj.Name, GlobalFunctions.Round(process.Amount)); } } } } UpdateProgressStatus(EnumProcessStatus.End); } private void AttendanceDayProcess() { UpdateProgressStatus(EnumProcessStatus.Start); AttnParametarization param = new AttnParametarizationService().Get(this.PayrollTypeID); // TermParameter ob = new TermParameter(); DateTime FirstDateOfMonth = GlobalFunctions.AttendanceMonthStart(this._processMonth, param.MonthStartDay); DateTime LastDateOfMonth = GlobalFunctions.AttendanceMonthEnd(this._processMonth, param.MonthStartDay); ; int TotalDaysInMonth = Convert.ToInt32( (LastDateOfMonth - FirstDateOfMonth).TotalDays + 1); //List attnProcess = DailyAttnProcess.Get(FirstDateOfMonth, LastDateOfMonth); DataSet dsAttnDaysSummary = new DailyAttnProcessService().AttnDaysSummaryForSalaryProcess(FirstDateOfMonth, LastDateOfMonth); if (dsAttnDaysSummary.Tables[0].Rows.Count <= 0) { UpdateProgressStatus(EnumProcessStatus.End); return; } double workingDays = 0.0, presentDays = 0.0, holidays = 0.0; foreach (SalaryMonthly sMonthly in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); DataRow dr = dsAttnDaysSummary.Tables[0].AsEnumerable().FirstOrDefault(x => Convert.ToInt32(x["EmployeeID"].ToString()) == sMonthly.EmployeeID); if (dr != null) { presentDays = Convert.ToDouble(dr["TotalPresent"].ToString()); holidays = Convert.ToDouble(dr["TotalHoliday"].ToString()); workingDays = Convert.ToDouble(dr["TotalDays"].ToString()); if (isMaternityOutsidePayroll && _empIDsMLPartial != null && _empIDsMLPartial.ContainsKey(sMonthly.EmployeeID)) { TimeSpan ts = _processMonth.LastDateOfMonth().Subtract(_empIDsMLPartial[sMonthly.EmployeeID].Date); workingDays = ts.Days; } this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Total_Days, (int)EnumSalaryItemCode.Total_Days, 0, "Working Days", workingDays); this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Tot_Attend_Days, (int)EnumSalaryItemCode.Tot_Attend_Days, 0, "Present Days", presentDays); this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Total_HoliDays, (int)EnumSalaryItemCode.Total_HoliDays, 0, "Holidays", holidays); } } UpdateProgressStatus(EnumProcessStatus.End); } private void LeaveDayProcess() { UpdateProgressStatus(EnumProcessStatus.Start); // TermParameter ob = new TermParameter(); DateTime PayrollFirstDateOfMonth = GlobalFunctions.FirstDateOfMonth(_processMonth); DateTime PayrollLastDateOfMonth = _processMonth; //int TotalDaysInMonth = SystemInformation.CurrentSysInfo.NextPayProcessDate.TotalDaysInMonth(); DataTable otab = new LeaveEntryService().GetSumOfBalance(PayrollFirstDateOfMonth, PayrollLastDateOfMonth, EnumLeaveStatus.Approved); List oleaves = new LeaveService().Get(EnumStatus.Regardless, this.PayrollTypeID); if (otab == null || otab.Rows.Count == 0) { UpdateProgressStatus(EnumProcessStatus.End); return; } foreach (SalaryMonthly sMonthly in _salaryMonthlys) { if (_empIDsLWOP != null && _empIDsLWOP.ContainsKey(sMonthly.EmployeeID)) { Leave lv = oleaves.FirstOrDefault(x => x.Code.Trim().ToUpper() == _lwopCode.Trim().ToUpper()); //this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Leave_Days, lv != null ? lv.ID : 0, // 0, lv != null ? lv.Code : "Leave Without Pay", _empIDsLWOP[sMonthly.EmployeeID]); } UpdateProgressStatus(EnumProcessStatus.PerformStep); DataRow[] foundRows = otab.Select("EMPID=" + sMonthly.EmployeeID); if (foundRows != null) { foreach (DataRow dr in foundRows) { // Get value of Calls here int leavid = Convert.ToInt32(dr["LEAVEID"]); double days = Convert.ToDouble(dr["totalDays"]); Leave ol = oleaves.FirstOrDefault(x => x.ID == leavid); this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Leave_Days, leavid, 0, ol.Description, days); } } } UpdateProgressStatus(EnumProcessStatus.End); } private void OverTimeArrearProcess() { //OvertimeProcess process = null; List otProcesses = null; List empOTProcesses = null; List oTerms = new TermService().Get(EnumStatus.Active, this.PayrollTypeID); double arrAMount = 0; List termparameters = new TermParameterService().GetByPayrollTypeID(this.PayrollTypeID); foreach (SalaryMonthly sMonthly in _salaryMonthlys) { arrAMount = 0; if (sMonthly.WIPIncrement > 0) { foreach (Term oterm in oTerms) { arrAMount = 0; foreach (EmployeeGradeSalary gradeSalary in sMonthly.ArrearGradeSalaries) { double amount = 0;// SalaryMonthly.Service.GetSumOnRangeOnRound(sMonthly.EmployeeID, GlobalFunctions.AttendanceSalaryMonth(gradeSalary.EffectDate), (DateTime)gradeSalary.TillDate, // EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Over_Time_Hours, oterm.ID, this.PayrollTypeID); //if (oterm.ID.Integer == 5) //{ // amount = amount + SalaryMonthly.Service.GetSumOnRangeOnRound(sMonthly.EmployeeID, PayrollPayrollGlobalFunctions.AttendanceSalaryMonth(gradeSalary.EffectDate), (DateTime)gradeSalary.TillDate, // EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, SystemInformation.CurrentSysInfo.PayrollTypeID.Integer); //} if (amount > 0) { TermParameter tp = TermParameter.GetParameter(termparameters, (int) sMonthly.Employee.GradeID, oterm.ID); if (tp != null) { amount = new OTProcessService().Calculate(tp, amount, sMonthly.WIPIncrement, _processMonth); // amount = amount * ( / 208) * (200 / 100); arrAMount = arrAMount + amount; } } } if (arrAMount > 0) this.AddDetail(sMonthly, EnumSalaryGroup.Arrear, EnumSalaryItemCode.Over_Time_Amount, oterm.ID, 0, oterm.Name, GlobalFunctions.Round(arrAMount)); } } } return; } private void CalculateBonus() { UpdateProgressStatus(EnumProcessStatus.Start); DateTime dSalaryMonth = this._processMonth; _bonusdetails = new BonusProcessService().GetBonusDetails(dSalaryMonth, true, this.PayrollTypeID); if (_bonusdetails == null || _bonusdetails.Count == 0) return; List bonuses = new BonusService().Get(EnumStatus.Regardless, this.PayrollTypeID); foreach (BonusProcess.BonusProcessDetail bonusdt in _bonusdetails) { UpdateProgressStatus(EnumProcessStatus.PerformStep); SalaryMonthly sMonthly = _salaryMonthlys.FirstOrDefault(x => x.EmployeeID == bonusdt.EmployeeID); if (sMonthly != null) { Bonus ob = bonuses.FirstOrDefault(x => x.ID == bonusdt.BonusID); this.AddDetail(sMonthly, EnumSalaryGroup.Gross, EnumSalaryItemCode.Bonus, bonusdt.BonusID, bonusdt.BonusProcessID, ob.Name, GlobalFunctions.Round(bonusdt.NetBonusAmount)); } } UpdateProgressStatus(EnumProcessStatus.End); } private void LoanProcess() { UpdateProgressStatus(EnumProcessStatus.Start); // DateTime dSalaryMonth = SystemInformation.CurrentSysInfo.NextPayProcessDate; // List loanIssues = LoanIssue.Service.Get(dSalaryMonth); // if (loanIssues == null || loanIssues.Count == 0) // { // UpdateProgressStatus(EnumProcessStatus.End); // return; // } // double nClosing = 0.0; //// bool withInerest = ConfigurationManager.GetBoolValue("loan", "combineinterestinsalary", EnumConfigurationType.Logic); // //List oLoanScheduls = new List(); // //oLoanScheduls = LoanSchedule.Get(); // List oschedules = LoanSchedule.Service.GetUnpaidSechedule(_processMonth); // foreach (LoanSchedule issue in oschedules) // { // UpdateProgressStatus(EnumProcessStatus.PerformStep); // SalaryMonthly sMonthly = _salaryMonthlys.Find(delegate(SalaryMonthly monthly) { return monthly.EmployeeID.Integer == issue.EmployeeID.Integer; }); // if (sMonthly != null) // { // sMonthly.CalculateTotal(); //// List oschedules = issue.Schedules; issue.MonthlySchedules(dSalaryMonth); // //if (oschedules == null) continue; // //foreach (LoanSchedule schedule in oschedules) // //{ //// nClosing = schedule.ClosingBalance; // this.AddDetail(sMonthly, EnumSalaryGroup.Deductions, EnumSalaryItemCode.Loan_Monthly_Installment, issue.LoanIssueID.Integer, schedule.ID.Integer, issue.LoanObj.Name, PayrollPayrollGlobalFunctions.Round(schedule.InstallmentPrincipal)); // this.AddDetail(sMonthly, EnumSalaryGroup.Deductions, EnumSalaryItemCode.Loan_Monthly_Interest, issue.LoanID.Integer, schedule.ID.Integer, issue.LoanObj.Name + " interest", PayrollPayrollGlobalFunctions.Round(schedule.InstallmentInterest)); // //} // this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Loan_Remain_Balance, issue.LoanID.Integer, issue.ID.Integer, issue.LoanObj.Name + " balance", PayrollPayrollGlobalFunctions.Round(nClosing)); // } // } DataSet oDataSet = new LoanScheduleService().GetScheduleForSalary(_processMonth, this.PayrollTypeID); if (oDataSet == null || oDataSet.Tables[0] == null || oDataSet.Tables[0].Rows.Count == 0) { UpdateProgressStatus(EnumProcessStatus.End); return; } foreach (DataRow oRow in oDataSet.Tables[0].Rows) { UpdateProgressStatus(EnumProcessStatus.PerformStep); SalaryMonthly sMonthly = _salaryMonthlys.Find(x => x.EmployeeID.ToString() == oRow["EMPLOYEEID"].ToString()); if (sMonthly != null) { sMonthly.CalculateTotal(); string partName = " Principle"; if(Convert.ToDouble(oRow["InstallmentInterest"].ToString()) ==0) { partName = ""; } this.AddDetail(sMonthly, EnumSalaryGroup.Deductions, EnumSalaryItemCode.Loan_Monthly_Installment, Convert.ToInt32(oRow["LOANID"].ToString()), Convert.ToInt32(oRow["LOANSCHEDULEID"].ToString()), oRow["DESCRIPTION"].ToString() + partName, GlobalFunctions.Round(Convert.ToDouble(oRow["InstallmentPrincipal"].ToString()))); this.AddDetail(sMonthly, EnumSalaryGroup.Deductions, EnumSalaryItemCode.Loan_Monthly_Interest, Convert.ToInt32(oRow["LOANID"].ToString()), Convert.ToInt32(oRow["LOANSCHEDULEID"].ToString()), oRow["DESCRIPTION"].ToString() + " Interest", GlobalFunctions.Round(Convert.ToDouble(oRow["InstallmentInterest"].ToString()))); // this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Loan_Remain_Balance, Convert.ToInt32(oRow["LOANID"].ToString()), Convert.ToInt32(oRow["LOANSCHEDULEID"].ToString()), oRow["DESCRIPTION"].ToString(), PayrollPayrollGlobalFunctions.Round(Convert.ToDouble(oRow["REMAININGAMOUNT"].ToString()))); // this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Loan_Remain_Interest, Convert.ToInt32(oRow["LOANID"].ToString()), Convert.ToInt32(oRow["LOANSCHEDULEID"].ToString()), oRow["DESCRIPTION"].ToString(), PayrollPayrollGlobalFunctions.Round(Convert.ToDouble(oRow["REMAINININTEREST"].ToString()))); } } UpdateProgressStatus(EnumProcessStatus.End); } private void Tax() { UpdateProgressStatus(EnumProcessStatus.Start); TaxCalculator taxCalculator = new TaxCalculator((int)this.payrollType.TaxParamID, this.payrollType.ID); taxCalculator.TaxParameter = new TaxParameterService().Get((int)this.payrollType.TaxParamID); taxCalculator.payrolltype = this.payrollType; taxCalculator.AdParameters = _adParameters; bool bfixedAmount = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic ,"incometax", "fixedamount" ); bool isOtherItem = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "incometax", "taxissalaryotheritem"); EnumSalaryGroup ngroupCode = EnumSalaryGroup.Deductions; if (isOtherItem == true) ngroupCode = EnumSalaryGroup.OtherItem; List taxes = new IncomeTaxService().Get(EnumIncomeTaxDataFrom.ProcessTempData, this.PayrollTypeID); foreach (SalaryMonthly salary in _salaryMonthlys) { salary.Incometaxes = new List(); UpdateProgressStatus(EnumProcessStatus.PerformStep); if (bfixedAmount == false) { if (salary.Employee.IsShownInTaxSheet == true) // Consaltant Tax { double contax = salary.Details.Where(x => x.itemGroupCode == EnumSalaryGroup.Gross).Sum(x => x.ChangedAmount); contax = contax + salary.Details.Where(x => x.itemGroupCode == EnumSalaryGroup.Arrear).Sum(x => x.ChangedAmount); this.AddDetail(salary, ngroupCode, EnumSalaryItemCode.Inc_Tax_Deduction, (int)EnumSalaryItemCode.Inc_Tax_Deduction, 0, string.Empty, GlobalFunctions.Round(contax * .1)); continue; } taxCalculator.Salary = salary; taxCalculator.Employee = salary.Employee; taxCalculator.AllowanceDeductions = _allowdeducitons; taxCalculator.PaidBonues = _bonusdetails; taxCalculator.CurrentYearTax = taxes.FindAll(x => x.EmployeeID == salary.EmployeeID); try { salary.Incometaxes = taxCalculator.SalaryTax(); } catch (ServiceException sx) { this.AddProcessStatus(salary.Employee, sx.Message); continue; } catch (Exception ex) { this.AddProcessStatus(salary.Employee, ex.Message); continue; } #region Include tax in salary IncomeTax taxItem = salary.Incometaxes.FirstOrDefault(x => x.ItemGroup == EnumIncomeTaxItemGroup.Tax_Deducted && x.ItemID == (int)EnumIncomeTaxItemGroup.Tax_Deducted); if (taxItem != null) { if (taxItem.ThisMonthAmount < 0) { this.AddDetail(salary, ngroupCode, EnumSalaryItemCode.Inc_Tax_Deduction, (int)EnumSalaryItemCode.Inc_Tax_Deduction, 0, string.Empty, GlobalFunctions.Round(0)); } else { if (salary.Employee.ForeignExPat == false) { salaryHistory ltaxItem = _PrvMonthsalaryItems.FirstOrDefault(x => x.empid == salary.EmployeeID && x.itemCode == EnumSalaryItemCode.Inc_Tax_Deduction); if (ltaxItem != null && salary.SalaryMonth.Month != 6) { if (Math.Abs(taxItem.ThisMonthAmount - ltaxItem.amount) <= 50) taxItem.ThisMonthAmount = ltaxItem.amount; } this.AddDetail(salary, ngroupCode, EnumSalaryItemCode.Inc_Tax_Deduction, (int)EnumSalaryItemCode.Inc_Tax_Deduction, 0, string.Empty, GlobalFunctions.Round(taxItem.ThisMonthAmount)); } else { taxItem.ThisMonthAmount = salary.Employee.TaxAmount; this.AddDetail(salary, ngroupCode, EnumSalaryItemCode.Inc_Tax_Deduction, (int)EnumSalaryItemCode.Inc_Tax_Deduction, 0, string.Empty, GlobalFunctions.Round(salary.Employee.TaxAmount)); } } } #endregion Include tax in salary } else { if (salary.Employee.TaxAmount > 0) { this.AddDetail(salary, ngroupCode, EnumSalaryItemCode.Inc_Tax_Deduction, (int)EnumSalaryItemCode.Inc_Tax_Deduction, 0, string.Empty, GlobalFunctions.Round(salary.Employee.TaxAmount)); } } } UpdateProgressStatus(EnumProcessStatus.End); } private void UnAuthorizeLeave() { UpdateProgressStatus(EnumProcessStatus.Start); List UnLeaves = new UnAuthorizeLeaveParamService().Get(this.PayrollTypeID, true); List empUnLeaves = new EmployeeUnAuthorizeLeaveService().Get(this.PayrollTypeID, _processMonth, null); //DataSet DocAndZleave = DailyAttnProcess.Service.GetZandDocLeaveDays(GlobalExtensions.PayrollFirstDateOfMonth(_processMonth), _processMonth); //if (DocAndZleave != null && DocAndZleave.Tables[0] != null && DocAndZleave.Tables[0].Rows.Count > 0) //{ // foreach (DataRow oRow in DocAndZleave.Tables[0].Rows) // { // EmployeeUnAuthorizeLeave uleave = new EmployeeUnAuthorizeLeave(); // uleave.LeaveDays = Convert.ToInt32(oRow["TOTAL"].ToString()); // uleave.EmployeeID = ( Convert.ToInt32(oRow["EMPLOYEEID"].ToString())); // uleave.UnAuthorizeleaveID = ( Convert.ToInt32(oRow["REFERENCEID"].ToString())); // uleave.ParamID = (Convert.ToInt32(oRow["REFERENCEID"].ToString())); // empUnLeaves.Add(uleave); // } //} //DateTime fromDate = _processMonth; //fromDate = fromDate.AddMonths(-1); //fromDate = new DateTime(fromDate.Year, fromDate.Month, 26); //DateTime toDate = _processMonth; //toDate = new DateTime(toDate.Year, toDate.Month, 25); //// DataSet absentDSet = new DailyAttnProcessService().GetTotalAbsentDays(fromDate, toDate); ////UnAuthorizeLeaveParam unAuthorizeLeaveParamGross = UnLeaves.Where(o => o.UnAuthorizeLeave.Code.Trim() == "001").FirstOrDefault(); ////UnAuthorizeLeaveParam unAuthorizeLeaveParamBasic = UnLeaves.Where(o => o.UnAuthorizeLeave.Code.Trim() == "002").FirstOrDefault(); double totalDaysOfMonth = GlobalFunctions.GetDaysInMonth(this._processMonth); //.FirstDateOfMonth .DateDiff("d", fromDate, toDate) + 1; // toDate.Subtract(fromDate).TotalDays; bool bEchoTexException = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "salary", "echotexexception"); //if (absentDSet != null && absentDSet.Tables[0].Rows.Count > 0) //{ // foreach (DataRow dor in absentDSet.Tables[0].Rows) // { // EmployeeUnAuthorizeLeave uleave = new EmployeeUnAuthorizeLeave(); // uleave.LeaveDays = Convert.ToInt32(dor["TOTAL"].ToString()); // uleave.EmployeeID = (Convert.ToInt32(dor["EMPLOYEEID"].ToString())); // uleave.LeaveMonth = _processMonth; // uleave.MonthDate = _processMonth; // uleave.UnAuthorizeleaveID = unAuthorizeLeaveParamGross.UnAhuthorizeLeaveID; // uleave.ParamID = unAuthorizeLeaveParamGross.ID; // empUnLeaves.Add(uleave); // } //} //if (empUnLeaves == null || empUnLeaves.Count == 0) //{ // UpdateProgressStatus(EnumProcessStatus.End); // return; //} foreach (SalaryMonthly salary in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); #region Unauthorize leave monthly calculation List empLeaves = empUnLeaves.FindAll(delegate (EmployeeUnAuthorizeLeave empLeave) { return empLeave.EmployeeID== salary.EmployeeID; }); SalaryMonthlyDetail salaryDetail = null; double nAmount = 0; //double totalAmount = 0; //totalAmount = 0; foreach (EmployeeUnAuthorizeLeave leave in empLeaves) { leave.Param = UnLeaves.Find(delegate (UnAuthorizeLeaveParam param) { return param.ID == leave.ParamID; }); if (leave.Param == null) { throw new Exception("Un-Authorize-Leave or Absent param not found"); } // totalAmount = 0; if (leave.Type == EnumLeaveEntryType.Normal) { foreach (UnAuthorizeLeaveParamDetail detail in leave.Param.Details) { salaryDetail = salary.Details.Find(delegate (SalaryMonthlyDetail dtl) { return IsExists(dtl, detail); }); if (salaryDetail == null) continue; if (leave.LeaveMonth == _processMonth) { if (salaryDetail != null) { nAmount = salaryDetail.CalculatedAmount; if (salary.Employee.JoiningDate > GlobalFunctions.FirstDateOfMonth(_processMonth)) { double ndays; ndays = Global.DateFunctions.DateDiff("d", salary.Employee.JoiningDate, _processMonth) + 1; nAmount = nAmount / ndays; nAmount = nAmount * _processMonth.Day; } } } else { nAmount = new SalaryMonthlyService().GetAmountOnRange(salary.Employee, GlobalFunctions.FirstDateOfMonth(leave.LeaveMonth), GlobalFunctions.LastDateOfMonth(leave.LeaveMonth), EnumSalaryGroup.Gross, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, null, null); } //nAmount = PayrollPayrollGlobalFunctions.ConevrtToDlyRateofMonth(nAmount, _processMonth) * leave.LeaveDays; //not 26 it will be Number of days from 26 to 25 double leaveDays = leave.LeaveDays; if (bEchoTexException == true) { if (_empIDsLWOP != null && _empIDsLWOP.ContainsKey(salary.Employee.ID)) { leaveDays += _empIDsLWOP[salary.Employee.ID]; } } nAmount = (nAmount / totalDaysOfMonth) * leaveDays; nAmount = nAmount * (detail.ValueInPercent / 100); //nAmount = PayrollPayrollGlobalFunctions.Round(nAmount); nAmount = Math.Round(nAmount, 2); // double nDays = (_processMonth.Month == 2) ? 30 : _processMonth.TotalDaysInMonth(); // nAmount = nAmount / nDays * totalDaysOfMonth; // nAmount = Math.Round(nAmount, 0); // totalAmount = totalAmount + nAmount; //} //else //{ var leaveItem = this.AddDetail(salary, EnumSalaryGroup.UnauthLeave, detail.Type == EnumSalaryComponent.Basic ? EnumSalaryItemCode.Basic_Salary : EnumSalaryItemCode.Allowance, detail.Type == EnumSalaryComponent.Basic ? (int)EnumSalaryItemCode.Basic_Salary : detail.AllowanceID, (int)salaryDetail.SupportID, salaryDetail.Description, GlobalFunctions.Round(nAmount)); leaveItem.Position = salaryDetail.Position; // } } //if (bEchoTexException == true) //{ // this.AddDetail(salary, EnumSalaryGroup.UnauthLeave, //EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, // 0, salaryDetail.Description, GlobalFunctions.Round(totalAmount)); //} this.AddDetail(salary, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Tot_UnauthLeave_Days, leave.Param.UnAhuthorizeLeaveID, 0, "UnAuthorized Leave Days", leave.LeaveDays); } else { SalaryMonthly oleaveSalary = new SalaryMonthlyService().Get(salary.EmployeeID, GlobalFunctions.LastDateOfMonth(leave.LeaveMonth)); if (oleaveSalary == null) { // throw new Exception("Salary not found for the unauthorize reserse calculation."); AddProcessStatus(salary.Employee, "There is no un-authorize leave deduction on the leave month."); continue; } double days = 0; SalaryMonthlyDetail od = oleaveSalary.Details.FirstOrDefault(x => x.itemGroupCode == EnumSalaryGroup.Miscellaneous && x.ItemID == leave.UnAuthorizeleaveID); if (od == null) { AddProcessStatus(salary.Employee, "There is no un-authorize leave deduction on the leave month."); continue; } days = od.ChangedAmount; SalaryMonthlyDetail unAutAdjustDays = oleaveSalary.Details.FirstOrDefault(x => x.itemGroupCode == EnumSalaryGroup.Miscellaneous && x.ItemCode == EnumSalaryItemCode.Tot_UnauthLeave_Adjust_Days); SalaryMonthlyDetail unAutDays = oleaveSalary.Details.FirstOrDefault(x => x.itemGroupCode == EnumSalaryGroup.Miscellaneous && x.ItemCode == EnumSalaryItemCode.Tot_UnauthLeave_Days); if (unAutAdjustDays != null && unAutDays != null) //Check if there are both normal and paid unauthorized leave exist in previous month and recalculate { double tempAmount = 0; UnAuthorizeLeaveParam param = UnLeaves.FirstOrDefault(x => x.UnAhuthorizeLeaveID == unAutDays.ItemID); foreach (SalaryMonthlyDetail odtl in oleaveSalary.Details) { if (odtl.itemGroupCode == EnumSalaryGroup.UnauthLeave) { UnAuthorizeLeaveParamDetail paramDetail = param.Details.FirstOrDefault(x => (x.Type == EnumSalaryComponent.Basic && odtl.ItemCode == EnumSalaryItemCode.Basic_Salary) || (x.Type == EnumSalaryComponent.Allowance && odtl.ItemID == x.AllowanceID)); SalaryMonthlyDetail tempsalary = oleaveSalary.Details.FirstOrDefault(x => x.itemGroupCode == EnumSalaryGroup.Gross && x.ItemCode == odtl.ItemCode && x.ItemID== odtl.ItemID); if (paramDetail == null) continue; tempAmount = (tempsalary.ChangedAmount / totalDaysOfMonth) * unAutDays.ChangedAmount; tempAmount = tempAmount * (paramDetail.ValueInPercent / 100); double adjustAmount = -(tempAmount / days) * leave.LeaveDays; this.AddDetail(salary, EnumSalaryGroup.UnauthLeave, odtl.ItemCode, odtl.ItemID, odtl.SupportID, odtl.Description, GlobalFunctions.Round(adjustAmount)); } } this.AddDetail(salary, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Tot_UnauthLeave_Adjust_Days, leave.Param.UnAhuthorizeLeaveID, 0, "UnAuthorized Adjust Leave Days", leave.LeaveDays); } else { foreach (SalaryMonthlyDetail odtl in oleaveSalary.Details) { if (odtl.itemGroupCode == EnumSalaryGroup.UnauthLeave) { double adjustAmount = -(odtl.ChangedAmount / days) * leave.LeaveDays; this.AddDetail(salary, EnumSalaryGroup.UnauthLeave, odtl.ItemCode, odtl.ItemID, odtl.SupportID, odtl.Description, GlobalFunctions.Round(adjustAmount)); } } this.AddDetail(salary, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Tot_UnauthLeave_Adjust_Days, leave.Param.UnAhuthorizeLeaveID, 0, "UnAuthorized Adjust Leave Days", leave.LeaveDays); } } } if (bEchoTexException == true) { if (_empIDsLWOP != null && _empIDsLWOP.ContainsKey(salary.Employee.ID) && empLeaves.Count ==0) { double ldays = _empIDsLWOP[salary.Employee.ID]; nAmount = (salary.ThisMonthBasic / totalDaysOfMonth) * ldays; nAmount = Math.Round(nAmount, 2); this.AddDetail(salary, EnumSalaryGroup.UnauthLeave, EnumSalaryItemCode.Basic_Salary , (int)EnumSalaryItemCode.Basic_Salary , 0, "Absent Deduction(Basic)", GlobalFunctions.Round(nAmount)); } } #endregion } UpdateProgressStatus(EnumProcessStatus.End); } private bool IsExists(SalaryMonthlyDetail dtl, UnAuthorizeLeaveParamDetail detail) { switch (detail.Type) { case EnumSalaryComponent.Basic: return dtl.ItemCode == EnumSalaryItemCode.Basic_Salary && dtl.itemGroupCode == EnumSalaryGroup.Gross; case EnumSalaryComponent.Allowance: return (dtl.ItemCode == EnumSalaryItemCode.Allowance && dtl.itemGroupCode == EnumSalaryGroup.Gross && dtl.ItemID == detail.AllowanceID); default: return false; } } private void PrepareCostcenterData() { UpdateProgressStatus(EnumProcessStatus.Start); List empCostCenters = new EmployeeCostCenterService().Get(); foreach (SalaryMonthly salary in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); List empinvolments = empCostCenters.FindAll(x=>x.EmployeeID == salary.EmployeeID); if (empCostCenters == null) continue; salary.CostCentersInvolments = new List(); if (empinvolments != null) { foreach (EmployeeCostCenter item in empinvolments) { SalaryEmpCostCenter Semp = new SalaryEmpCostCenter(); Semp.CostCenterID = item.CostCenterID; Semp.Percentage = item.Percentage; Semp.EmployeeID = salary.EmployeeID; salary.CostCentersInvolments.Add(Semp); } } } UpdateProgressStatus(EnumProcessStatus.End); } public double CalculateInvertedGrossFraction(DateTime month, int employeeID = 0) { return 1.0 / CalculateGrossFraction(month, employeeID); } public double CalculateGrossFraction(DateTime month, int employeeID = 0) { double grossFraction = 1; //List _attendanceForGrossFraction; if (month.LastDateOfMonth().Date == new DateTime(2020, 4, 30)) { grossFraction = 0.6; } else if (month.LastDateOfMonth().Date == new DateTime(2020, 5, 31)) { grossFraction = 0.65; if (_attendanceForGrossFraction == null) { CalculateEmployeeAttendanceForGrossFraction(month.LastDateOfMonth().Date); } var attnForFraction = _attendanceForGrossFraction.FirstOrDefault(x => x.EmployeeID == employeeID); if (attnForFraction != null) { grossFraction = ((attnForFraction.PresentDays * 100.00) + (attnForFraction.AbsentDays * 65.00)) / (attnForFraction.TotalDays * 100); } } return grossFraction; } public void CalculateEmployeeAttendanceForGrossFraction(DateTime month) { DataSet dsAttnDaysSummary = new DailyAttnProcessService().AttnDaysSummaryForSalaryProcess(month.FirstDateOfMonth(), month.LastDateOfMonth()); List leaveEntries = new LeaveEntryService().Get(month.FirstDateOfMonth(), month.LastDateOfMonth(), EnumLeaveStatus.Approved); List leaves = new LeaveService().GetAll(); int maternityLeaveID = 0; int lwpLeaveID = 0; if (string.IsNullOrWhiteSpace(_maternityCode) || string.IsNullOrWhiteSpace(_lwopCode)) { CollectLeaveCodesFromLogic(); } if (leaves.Any(x => x.Code.Trim().ToUpper() == _maternityCode.Trim().ToUpper())) { maternityLeaveID = leaves.First(x => x.Code.Trim().ToUpper() == _maternityCode.Trim().ToUpper()).ID; } if (leaves.Any(x => x.Code.Trim().ToUpper() == _lwopCode.Trim().ToUpper())) { lwpLeaveID = leaves.First(x => x.Code.Trim().ToUpper() == _lwopCode.Trim().ToUpper()).ID; } DataRow attendanceDR; double totalDays, absentDays, presentDays; totalDays = month.LastDateOfMonth().Day; foreach (var salary in _salaryMonthlys) { attendanceDR = dsAttnDaysSummary.Tables[0].AsEnumerable().FirstOrDefault(x => Convert.ToInt32(x["EmployeeID"].ToString()) == salary.EmployeeID); presentDays = absentDays = 0.0; //totalDays = Convert.ToDouble(attendanceDR["TotalDays"].ToString()); presentDays += Convert.ToDouble(attendanceDR["TotalPresent"].ToString()) + Convert.ToDouble(attendanceDR["TotalHoliday"].ToString()); presentDays += leaveEntries.Where(x => x.EmpID == salary.EmployeeID && x.LeaveID != maternityLeaveID && x.LeaveID != lwpLeaveID) .Sum(x => x.ApprovedTotalDays); absentDays = totalDays - presentDays; _attendanceForGrossFraction.Add(new AttendanceForGrossFraction(salary.EmployeeID, presentDays, absentDays)); } // public static void PrepareDataForMaternityLeaveReturnCurrentSalary(Employee employee, //List gradeSalaries, DateTime returnDate) // { // DateTime from = returnDate; // DateTime toDate = ; // gradeSalaries[gradeSalaries.Count - 1].TillDate = toDate; // if (employee.EndOfContractDate != null && employee.EndOfContractDate != DateTime.MinValue) // if (employee.EndOfContractDate < toDate) // gradeSalaries[gradeSalaries.Count - 1].TillDate = employee.EndOfContractDate; // foreach (EmployeeGradeSalary item in gradeSalaries) // { // if (item.ArrearType == EnumArrearType.NotPresent) // { // if (item.EffectDate < GlobalFunctions.FirstDateOfMonth(toDate)) // { // item.EffectDate = GlobalFunctions.FirstDateOfMonth(toDate); // } // } // item.FractionofFromTo = GlobalFunctions.GetFraction(from > item.EffectDate ? from : item.EffectDate, item.TillDate != null ? (DateTime)item.TillDate : toDate); // // total = total + item.FractionofFromTo; // } // } } private void CollectMaternityLeaveData() { bool bEchoTexException = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "salary", "echotexexception"); if (bEchoTexException == false) return; isMaternityOutsidePayroll = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "leave", "maternityoutsidepayroll"); if (isMaternityOutsidePayroll) { CollectLeaveCodesFromLogic(); if (!string.IsNullOrWhiteSpace(_maternityCode)) { DateTime startDate = _processMonth.FirstDateOfMonth(), endDate = _processMonth.LastDateOfMonth(); string sql = string.Format(@"SELECT Distinct EMPID FROM LEAVEENTRY e WHERE (e.APRFROMDATE BETWEEN '{0}' AND '{1}' OR e.APRTODATE BETWEEN '{0}' AND '{1}' OR '{0}' BETWEEN e.APRFROMDATE AND e.APRTODATE ) AND e.APRTODATE >= '{1}' AND LEAVEID = (SELECT TOP 1 LeaveID FROM LEAVE WHERE CODE ='{2}') ORDER BY EMPID SELECT DISTINCT EMPID,APRTODATE FROM LEAVEENTRY e WHERE (e.APRFROMDATE BETWEEN '{0}' AND '{1}' OR e.APRTODATE BETWEEN '{0}' AND '{1}' OR '{0}' BETWEEN e.APRFROMDATE AND e.APRTODATE ) AND e.APRTODATE < '{1}' AND LEAVEID = (SELECT TOP 1 LeaveID FROM LEAVE WHERE CODE ='{2}') ORDER BY e.EMPID,e.APRTODATE SELECT EMPID, iif(APRFROMDATE<'{0}','{0}',APRFromDate) FromDate, iif(APRTODATE>'{1}','{1}',APRTODATE) ToDate FROM LEAVEENTRY e WHERE (e.APRFROMDATE BETWEEN '{0}' AND '{1}' OR e.APRTODATE BETWEEN '{0}' AND '{1}' OR '{0}' BETWEEN e.APRFROMDATE AND e.APRTODATE ) AND LEAVEID = (SELECT TOP 1 LeaveID FROM LEAVE WHERE CODE ='{3}') ORDER BY EMPID,APRFROMDATE,APRTODATE", startDate.ToString("dd MMM yyyy"), endDate.ToString("dd MMM yyyy"), _maternityCode, _lwopCode); DataSet ds = new MiscellaneousDatasetService().GetDataSetBySQL(sql); if (ds.Tables.Count> 0 && ds.Tables[0].Rows.Count > 0) { _empIDsforMLRemoval = ds.Tables[0].AsEnumerable().Select(x => x.Field("EMPID")).ToList(); } if (ds.Tables.Count > 1 && ds.Tables[1].Rows.Count > 0) { _empIDsMLPartial = ds.Tables[1].AsEnumerable().Select(x => new { Key = x.Field("EMPID"), Value = x.Field("APRTODATE") }).ToLookup(t => t.Key, t => t.Value).ToDictionary(x => x.Key, x => x.First()); } if (ds.Tables.Count > 2 && ds.Tables[2].Rows.Count > 0) { //_empIDsforLWOPRemoval = new List(); _empIDsLWOP = new Dictionary(); foreach (DataRow item in ds.Tables[2].Rows) { int days = item.Field("ToDate").Date.Subtract(item.Field("FromDate").Date).Days + 1; if (_empIDsLWOP.ContainsKey(item.Field("EMPID"))) { _empIDsLWOP[item.Field("EMPID")] = _empIDsLWOP[item.Field("EMPID")] + days; } else { _empIDsLWOP.Add(item.Field("EMPID"), days); } #region Commented Code for LWOP total salary removal // if(_empIDsMLPartial.ContainsKey(item.Field("EMPID"))) // { // DateTime maternityEnd = _empIDsMLPartial[item.Field("EMPID")]; // if(maternityEnd.AddDays(1).Date >= item.Field("FromDate").Date && // item.Field("ToDate").Date == endDate) // { // _empIDsforLWOPRemoval.Add(item.Field("EMPID")); // } // else // { // _empIDsMLPartial[item.Field("EMPID")] = maternityEnd.AddDays(item.Field("ToDate").Date.Subtract(item.Field("FromDate").Date).Days + 1); // } // } // else // { // int days = item.Field("ToDate").Date.Subtract(item.Field("FromDate").Date).Days + 1; // if((endDate.Subtract(startDate).Days +1) == days) // { // _empIDsforLWOPRemoval.Add(item.Field("EMPID")); // } // else // { // if (_empIDsLWOP.ContainsKey(item.Field("EMPID"))) // { // if((endDate.Subtract(startDate).Days +1) == (_empIDsLWOP[item.Field("EMPID")]+days)) // { // _empIDsforLWOPRemoval.Add(item.Field("EMPID")); // } // else // { // _empIDsLWOP[item.Field("EMPID")] = _empIDsLWOP[item.Field("EMPID")] + days; // } // } // else // { // _empIDsLWOP.Add(item.Field("EMPID"), days); // } // } // } //} #endregion } } } } } private void CollectLeaveCodesFromLogic() { _maternityCode =new SystemConfigarationService().GetconfigStringValue(EnumConfigurationType.Logic, "leave", "maternitycode"); if (string.IsNullOrWhiteSpace(_maternityCode)) { _maternityCode = "ML"; } _lwopCode = new SystemConfigarationService().GetconfigStringValue(EnumConfigurationType.Logic, "leave", "lwopcode" ); if (string.IsNullOrWhiteSpace(_lwopCode)) { _lwopCode = "LWOP"; } } private class AttendanceForGrossFraction { public AttendanceForGrossFraction(int employeeID, double presentDays, double absentDays) { EmployeeID = employeeID; PresentDays = presentDays; AbsentDays = absentDays; } public int EmployeeID { get; private set; } public double PresentDays { get; private set; } public double AbsentDays { get; private set; } public double TotalDays { get { return PresentDays + AbsentDays; } } } } public class SalaryException { #region Define Class Veriable List oAllDeducts; List oAttnProcesses; List oShifts; List oLeaves; public DateTime _processMonth; #endregion Define Class Veriable public SalaryException() { } public void SalaryExceptionCalculation(SalaryCalculator scalculator) { bool bEchoTexException = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "salary", "echotexexception"); #region Echo-Tex Exception try { if (bEchoTexException == true) { oAllDeducts = new AllowanceDeductionService().Get(EnumStatus.Regardless, scalculator.PayrollTypeID); oShifts = new ShiftService().Get(string.Empty, string.Empty, EnumStatus.Regardless, scalculator.PayrollTypeID); oLeaves = new LeaveService().Get(EnumStatus.Regardless, string.Empty, string.Empty, scalculator.PayrollTypeID); #region Attendance Bonus Exception Leave lvwop = oLeaves.FirstOrDefault(x => x.Code.Trim().ToUpper() == scalculator._lwopCode.Trim().ToUpper()); AllowanceDeduction oAttnAllowance = oAllDeducts.FirstOrDefault(x => x.Code.Trim().ToUpper() == "001" && x.AllowOrDeductType == EnumAllowOrDeduct.Allowance); if (oAttnAllowance != null ) { foreach (SalaryMonthly sMonthly in scalculator.SalaryMonthlies) { double absentDays = sMonthly.Details.Where(x => x.itemGroupCode == EnumSalaryGroup.Miscellaneous && x.ItemCode == EnumSalaryItemCode.Tot_UnauthLeave_Days).Sum(x => x.ChangedAmount); if (lvwop != null) { absentDays += sMonthly.Details.Where(x => x.itemGroupCode == EnumSalaryGroup.Miscellaneous && x.ItemCode == EnumSalaryItemCode.Leave_Days && x.ItemID == lvwop.ID).Sum(x => x.ChangedAmount); } if (absentDays > 0 || sMonthly.Employee.JoiningDate.Date > GlobalFunctions.FirstDateOfMonth(sMonthly.SalaryMonth).AddDays(5)) { List oMonthlyDetails = sMonthly.Details.Where(x => x.itemGroupCode == EnumSalaryGroup.Gross && x.ItemCode == EnumSalaryItemCode.Allowance && x.ItemID == oAttnAllowance.ID).ToList(); foreach (SalaryMonthlyDetail item in oMonthlyDetails) { int ind = sMonthly.Details.FindIndex(x => x.itemGroupCode == EnumSalaryGroup.Gross && x.ItemCode == EnumSalaryItemCode.Allowance && x.ItemID == oAttnAllowance.ID); sMonthly.Details.RemoveAt(ind); } } else { List oMonthlyDetails = sMonthly.Details.Where(x => x.itemGroupCode == EnumSalaryGroup.Gross && x.ItemCode == EnumSalaryItemCode.Allowance && x.ItemID == oAttnAllowance.ID).ToList(); UndoProrated(sMonthly, oMonthlyDetails); } } } #endregion #region Conduct Bonus Exception oAttnAllowance = oAllDeducts.FirstOrDefault(x => x.Code.Trim().ToUpper() == "002" && x.AllowOrDeductType == EnumAllowOrDeduct.Allowance); if (oAttnAllowance != null ) { foreach (SalaryMonthly sMonthly in scalculator.SalaryMonthlies) { double absentDays = sMonthly.Details.Where(x => x.itemGroupCode == EnumSalaryGroup.Miscellaneous && x.ItemCode == EnumSalaryItemCode.Tot_UnauthLeave_Days).Sum(x => x.ChangedAmount); if (lvwop != null) { absentDays += sMonthly.Details.Where(x => x.itemGroupCode == EnumSalaryGroup.Miscellaneous && x.ItemCode == EnumSalaryItemCode.Leave_Days && x.ItemID == lvwop.ID).Sum(x => x.ChangedAmount); } if (absentDays > 3 || sMonthly.Employee.JoiningDate > GlobalFunctions.FirstDateOfMonth(sMonthly.SalaryMonth).AddDays(5)) { List oMonthlyDetails = sMonthly.Details.Where(x => x.itemGroupCode == EnumSalaryGroup.Gross && x.ItemCode == EnumSalaryItemCode.Allowance && x.ItemID == oAttnAllowance.ID).ToList(); foreach (SalaryMonthlyDetail item in oMonthlyDetails) { int ind = sMonthly.Details.FindIndex(x => x.itemGroupCode == EnumSalaryGroup.Gross && x.ItemCode == EnumSalaryItemCode.Allowance && x.ItemID == item.ItemID); sMonthly.Details.RemoveAt(ind); // sMonthly.Details.Remove(item); } } else { List oMonthlyDetails = sMonthly.Details.Where(x => x.itemGroupCode == EnumSalaryGroup.Gross && x.ItemCode == EnumSalaryItemCode.Allowance && x.ItemID == oAttnAllowance.ID).ToList(); // This Is Done Because Conduct Bonus Will not be prorated UndoProrated(sMonthly, oMonthlyDetails); } } } #endregion oAttnProcesses = new DailyAttnProcessService().GetshotList(GlobalFunctions.FirstDateOfMonth(scalculator._processMonth), scalculator._processMonth); #region Attn Related Allowance Exception AllowanceDeduction oAttnExtraAllowance = oAllDeducts.FirstOrDefault(x => x.Code.Trim().ToUpper() == "004" && x.AllowOrDeductType == EnumAllowOrDeduct.Allowance); AllowanceDeduction oAttnLunchAssistanceAllowance = oAllDeducts.FirstOrDefault(x => x.Code.Trim().ToUpper() == "015" && x.AllowOrDeductType == EnumAllowOrDeduct.Allowance); string lunchAllowDaysString = new SystemConfigarationService().GetconfigStringValue(EnumConfigurationType.Logic, "attendence", "lunchallowanceday").ToString(); DayOfWeek lunchAllowanceDOW; if (!Enum.TryParse(lunchAllowDaysString, out lunchAllowanceDOW)) lunchAllowanceDOW = DayOfWeek.Friday; string excludedLunchAllowDatesString = new SystemConfigarationService().GetconfigStringValue(EnumConfigurationType.Logic, "attendence", "excludedlunchallowancedates"); // string excludedLunchAllowDatesString = ConfigurationManager.GetStringValue("attendence", "excludedlunchallowancedates", EnumConfigurationType.Logic); List excludedLunchAllowDates = new List(); if (!string.IsNullOrWhiteSpace(excludedLunchAllowDatesString)) { try { excludedLunchAllowDates = excludedLunchAllowDatesString.Split(',').Select(x => DateTime.Parse(x)).ToList(); } catch (Exception) { // If error occurs during parsing, then there will be no excvluded Days } } List oOverlappingShiftIDs = oShifts.Where(x => x.IsOverlapingDay).Select(x => x.ID).ToList(); AllowanceDeduction oAttnTifinAllowance = oAllDeducts.FirstOrDefault(x => x.Code.Trim().ToUpper() == "016" && x.AllowOrDeductType == EnumAllowOrDeduct.Allowance); string tiffinAllowanceCodeString = new SystemConfigarationService().GetconfigStringValue(EnumConfigurationType.Logic, "attendence", "nightshiftcodes"); // string tiffinAllowanceCodeString = new SystemConfigarationService().GetconfigValue(EnumConfigurationType.Logic, "attendence", "nightshiftcodes").ToString(); List tiffinAllowanceCodes = tiffinAllowanceCodeString.Trim().Split(',').ToList(); //string sExtraAllowanceHour = Ease.CoreV35.Utility.ConfigUtility.GetAppSettings("ExtraAllowanceHour"); //if (!double.TryParse(sExtraAllowanceHour, out dExtraAllowanceHours)) //{ // dExtraAllowanceHours = 13.5; // Default if Hour not given //} object ab = new SystemConfigarationService().GetconfigValue(EnumConfigurationType.Logic, "attendence", "extraallowancehour"); double dExtraAllowanceHours = 13.5; if (ab != null) dExtraAllowanceHours = Convert.ToDouble(ab); // string tiffinAllowanceCodeString = ConfigurationManager.GetStringValue("attendence", "ExtraAllowanceHour", EnumConfigurationType.Logic); List oNationalHolidays = new AttnNationalHolidayService().GetByMonthAndPayrollType( Ease.Core.Utility.Global.DateFunctions.FirstDateOfYear(scalculator._processMonth) , Ease.Core.Utility.Global.DateFunctions.LastDateOfYear(scalculator._processMonth), scalculator.PayrollTypeID); foreach (SalaryMonthly sMonthly in scalculator.SalaryMonthlies) { List smTempDetails = new List(); List oEmpDailAttnProcesses = null; #region Extra Allowance if (oAttnExtraAllowance != null && sMonthly.Details.Any(y => y.itemGroupCode == EnumSalaryGroup.Gross && y.ItemCode == EnumSalaryItemCode.Allowance && y.ItemID == oAttnExtraAllowance.ID)) { oEmpDailAttnProcesses = oAttnProcesses.Where(x => x.EmployeeID == sMonthly.EmployeeID).ToList(); DateTime startTime; DateTime? endTime; double multiplier = 0; if (oEmpDailAttnProcesses != null) { foreach (DailyAttnProcess dAttn in oEmpDailAttnProcesses) { if (dAttn.InTime !=null && dAttn.InTime != DateTime.MinValue) { Shift sft = oShifts.FirstOrDefault(x => x.ID == dAttn.ShiftID); startTime = ((DateTime)dAttn.InTime).Date.Add(sft.InTime.TimeOfDay); startTime = ((DateTime)startTime).AddMinutes(-15) > (DateTime)dAttn.InTime ? Convert.ToDateTime(startTime).AddMinutes(-15) : (DateTime)dAttn.InTime; endTime = dAttn.OutTime; if (endTime !=null && endTime != DateTime.MinValue) { if (((DateTime)endTime).Subtract(startTime).Add(TimeSpan.FromMinutes(1)).TotalHours >= dExtraAllowanceHours) { multiplier++; } } } } } List oMonthlyDetails = sMonthly.Details.Where(y => y.itemGroupCode == EnumSalaryGroup.Gross && y.ItemCode == EnumSalaryItemCode.Allowance && y.ItemID == oAttnExtraAllowance.ID).ToList(); UndoProrated(sMonthly, oMonthlyDetails); foreach (SalaryMonthlyDetail smDetail in oMonthlyDetails) { smDetail.ChangedAmount = smDetail.ChangedAmount * multiplier; smDetail.CalculatedAmount = smDetail.CalculatedAmount * multiplier; scalculator.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Extra_Allowance_Days, oAttnExtraAllowance.ID, oAttnExtraAllowance.ID, Convert.ToString(EnumSalaryItemCode.Extra_Allowance_Days).Replace('_', ' '), multiplier); } } #endregion #region Lunch Assistance Allowance if (oAttnLunchAssistanceAllowance != null && sMonthly.Details.Any(y => y.itemGroupCode == EnumSalaryGroup.Gross && y.ItemCode == EnumSalaryItemCode.Allowance && y.ItemID == oAttnLunchAssistanceAllowance.ID)) { if (oEmpDailAttnProcesses == null) oEmpDailAttnProcesses = oAttnProcesses.Where(x => x.EmployeeID == sMonthly.EmployeeID).ToList(); double multiplier = 0; multiplier = oEmpDailAttnProcesses.Where(x => x.AttnDate.DayOfWeek == lunchAllowanceDOW && x.AttenType != EnumAttendanceType.Absent && x.AttenType != EnumAttendanceType.Holiday && x.AttenType != EnumAttendanceType.Leave && x.AttenType != EnumAttendanceType.WeeklyHoliday && !excludedLunchAllowDates.Contains(x.AttnDate.Date) && !oOverlappingShiftIDs.Contains((x.ShiftID != null) ? (int)x.ShiftID : 0)) .Count(); List oMonthlyDetails = sMonthly.Details.Where(y => y.itemGroupCode == EnumSalaryGroup.Gross && y.ItemCode == EnumSalaryItemCode.Allowance && y.ItemID == oAttnLunchAssistanceAllowance.ID).ToList(); UndoProrated(sMonthly, oMonthlyDetails); foreach (SalaryMonthlyDetail smDetail in oMonthlyDetails) { scalculator.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Lunch_Allowance_Days, oAttnLunchAssistanceAllowance.ID, oAttnLunchAssistanceAllowance.ID, Convert.ToString(EnumSalaryItemCode.Lunch_Allowance_Days).Replace('_', ' '), multiplier); scalculator.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Lunch_Allowance_Rate, oAttnLunchAssistanceAllowance.ID, oAttnLunchAssistanceAllowance.ID, Convert.ToString(EnumSalaryItemCode.Lunch_Allowance_Rate).Replace('_', ' '), smDetail.ChangedAmount != 0 ? smDetail.ChangedAmount : smDetail.ChangedAmount); smDetail.ChangedAmount = smDetail.ChangedAmount * multiplier; smDetail.CalculatedAmount = smDetail.CalculatedAmount * multiplier; } } #endregion #region Tifin Allowance if (oAttnTifinAllowance != null && sMonthly.Details.Any(y => y.itemGroupCode == EnumSalaryGroup.Gross && y.ItemCode == EnumSalaryItemCode.Allowance && y.ItemID == oAttnTifinAllowance.ID)) { if (oEmpDailAttnProcesses == null) oEmpDailAttnProcesses = oAttnProcesses.Where(x => x.EmployeeID == sMonthly.EmployeeID).ToList(); double multiplier = 0; //List oShiftIDs = sMonthly.GradeSalaries.SelectMany(x => x.ADParameters).Where(y => y.AllowDeductID == //oAttnTifinAllowance.ID).SelectMany(z => z.ADParameterShifts).Select(a => a.ShiftID.Integer).ToList(); var tfshifts = oShifts.FindAll(x => x.TiffinAllowanceID != null); if (tfshifts != null) { List oShiftIDs = tfshifts.Select(a => a.ID).ToList(); multiplier = oEmpDailAttnProcesses.Where(x => x.ShiftID != null && oShiftIDs.Contains((int)x.ShiftID) && x.AttenType != EnumAttendanceType.Absent && x.AttenType != EnumAttendanceType.Holiday && x.AttenType != EnumAttendanceType.Leave && x.AttenType != EnumAttendanceType.WeeklyHoliday) .Count(); List oMonthlyDetails = sMonthly.Details.Where(y => y.itemGroupCode == EnumSalaryGroup.Gross && y.ItemCode == EnumSalaryItemCode.Allowance && y.ItemID == oAttnTifinAllowance.ID).ToList(); UndoProrated(sMonthly, oMonthlyDetails); foreach (SalaryMonthlyDetail smDetail in oMonthlyDetails) { scalculator.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Tifin_Allowance_Days, oAttnTifinAllowance.ID, oAttnTifinAllowance.ID, Convert.ToString(EnumSalaryItemCode.Tifin_Allowance_Days).Replace('_', ' '), multiplier); scalculator.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Tifin_Allowance_Rate, oAttnTifinAllowance.ID, oAttnTifinAllowance.ID, Convert.ToString(EnumSalaryItemCode.Tifin_Allowance_Rate).Replace('_', ' '), smDetail.ChangedAmount != 0 ? smDetail.ChangedAmount : smDetail.ChangedAmount); smDetail.ChangedAmount = smDetail.ChangedAmount * multiplier; smDetail.CalculatedAmount = smDetail.CalculatedAmount * multiplier; } } } #endregion #region Night shift allowance AllowanceDeduction oAttnNightAllowance = oAllDeducts.FirstOrDefault(x => x.Code.Trim().ToUpper() == "023" && x.AllowOrDeductType == EnumAllowOrDeduct.Allowance); if (oAttnNightAllowance != null && sMonthly.Details.Any(y => y.itemGroupCode == EnumSalaryGroup.Gross && y.ItemCode == EnumSalaryItemCode.Allowance && y.ItemID == oAttnNightAllowance.ID)) { if (oEmpDailAttnProcesses == null) oEmpDailAttnProcesses = oAttnProcesses.Where(x => x.EmployeeID == sMonthly.EmployeeID).ToList(); double multiplier = 0; bool IsApplicable = true; List oAdEmps = sMonthly.GradeSalaries.SelectMany(x => x.ADParameters).Where(y => y.AllowDeductID == oAttnNightAllowance.ID).SelectMany(z => z.ADParameterEmployees).ToList(); if (oAdEmps != null && oAdEmps.Count > 0) { foreach (ADParameterEmployee adEmp in oAdEmps) { if (oAttnNightAllowance.ID == adEmp.AllowDeductID && sMonthly.EmployeeID == adEmp.EmployeeID) { IsApplicable = false; break; } } } //List oShiftIDs = sMonthly.GradeSalaries.SelectMany(x => x.ADParameters).Where(y => y.AllowDeductID == //oAttnNightAllowance.ID).SelectMany(z => z.ADParameterShifts).Select(a => a.ShiftID.Integer).ToList(); var tfshifts = oShifts.FindAll(x => x.HasNightAllowance ==true); List oShiftIDs = tfshifts.Select(a => a.ID).ToList(); multiplier = oEmpDailAttnProcesses.Where(x => x.ShiftID != null && oShiftIDs.Contains((int)x.ShiftID) && x.AttenType != EnumAttendanceType.Absent && x.AttenType != EnumAttendanceType.Holiday && x.AttenType != EnumAttendanceType.Leave && x.AttenType != EnumAttendanceType.WeeklyHoliday) .Count(); List oMonthlyDetails = sMonthly.Details.Where(y => y.itemGroupCode == EnumSalaryGroup.Gross && y.ItemCode == EnumSalaryItemCode.Allowance && y.ItemID == oAttnNightAllowance.ID).ToList(); // UndoProrated(sMonthly, oMonthlyDetails); //if (multiplier > 0) //{ if (IsApplicable) { foreach (SalaryMonthlyDetail smDetail in oMonthlyDetails) { smDetail.ChangedAmount = smDetail.ChangedAmount * multiplier; smDetail.CalculatedAmount = smDetail.CalculatedAmount * multiplier; scalculator.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Night_Allowance_Days, oAttnNightAllowance.ID, oAttnNightAllowance.ID, Convert.ToString(EnumSalaryItemCode.Night_Allowance_Days).Replace('_', ' '), multiplier); scalculator.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Night_Allowance_Rate, oAttnNightAllowance.ID, oAttnNightAllowance.ID, Convert.ToString(EnumSalaryItemCode.Night_Allowance_Rate).Replace('_', ' '), smDetail.ChangedAmount == 0 ? 0 : (smDetail.ChangedAmount / multiplier)); } } else { if (oMonthlyDetails != null && oMonthlyDetails.Count > 0) { int indx = sMonthly.Details.FindIndex(x => x.itemGroupCode == oMonthlyDetails[0].itemGroupCode && x.ItemCode == oMonthlyDetails[0].ItemCode && x.ItemID == oMonthlyDetails[0].ItemID); // sMonthly.Details.Remove(oMonthlyDetails[0]); sMonthly.Details.RemoveAt(indx); } } // } } #endregion #region National Holiday allowance AllowanceDeduction oNHAllowance = oAllDeducts.FirstOrDefault(x => x.Code.Trim().ToUpper() == "028" && x.AllowOrDeductType == EnumAllowOrDeduct.Allowance); if (oNHAllowance != null && sMonthly.Details.Any(y => y.itemGroupCode == EnumSalaryGroup.Gross && y.ItemCode == EnumSalaryItemCode.Allowance && y.ItemID == oNHAllowance.ID)) { if (oEmpDailAttnProcesses == null) oEmpDailAttnProcesses = oAttnProcesses.Where(x => x.EmployeeID == sMonthly.EmployeeID).ToList(); double multiplier = 0; foreach (DailyAttnProcess dp in oEmpDailAttnProcesses) { if (dp.InTime !=null && dp.InTime != DateTime.MinValue) { AttnNationalHoliday nh = oNationalHolidays.Find(x => dp.AttnDate >= x.FromDate && dp.AttnDate <= x.ToDate); if (nh != null) multiplier++; } } bool IsApplicable = true; List oAdEmps = sMonthly.GradeSalaries.SelectMany(x => x.ADParameters).Where(y => y.AllowDeductID == oNHAllowance.ID).SelectMany(z => z.ADParameterEmployees).ToList(); if (oAdEmps != null && oAdEmps.Count > 0) { foreach (ADParameterEmployee adEmp in oAdEmps) { if (oNHAllowance.ID == adEmp.AllowDeductID && sMonthly.EmployeeID == adEmp.EmployeeID) { IsApplicable = false; break; } } } List oMonthlyDetails = sMonthly.Details.Where(y => y.itemGroupCode == EnumSalaryGroup.Gross && y.ItemCode == EnumSalaryItemCode.Allowance && y.ItemID == oNHAllowance.ID).ToList(); if (IsApplicable) { double ndays = 30;// _processMonth.LastDateOfMonth().Subtract(sMonthly.Employee.JoiningDate.Date).TotalDays + 1; double nAmountPerDay = sMonthly.ThisMonthGross / ndays; foreach (SalaryMonthlyDetail smDetail in oMonthlyDetails) { smDetail.ChangedAmount = nAmountPerDay * 2 * multiplier; smDetail.CalculatedAmount = nAmountPerDay * 2 * multiplier; scalculator.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.National_Holiday_Allowance_Days, oNHAllowance.ID, oNHAllowance.ID, Convert.ToString(EnumSalaryItemCode.National_Holiday_Allowance_Days).Replace('_', ' '), multiplier); scalculator.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.National_Holiday_Allowance_Rate, oNHAllowance.ID, oNHAllowance.ID, Convert.ToString(EnumSalaryItemCode.National_Holiday_Allowance_Rate).Replace('_', ' '), nAmountPerDay); } } else { if (oMonthlyDetails != null && oMonthlyDetails.Count > 0) { int indx = sMonthly.Details.FindIndex(x => x.itemGroupCode == oMonthlyDetails[0].itemGroupCode && x.ItemCode == oMonthlyDetails[0].ItemCode && x.ItemID == oMonthlyDetails[0].ItemID); sMonthly.Details.RemoveAt(indx); // sMonthly.Details.Remove(oMonthlyDetails[0]); } } // } } #endregion #region special allowance AllowanceDeduction oAttnSpacialAllowance = oAllDeducts.FirstOrDefault(x => x.Code.Trim().ToUpper() == "022" && x.AllowOrDeductType == EnumAllowOrDeduct.Allowance); if (oAttnSpacialAllowance != null && sMonthly.Details.Any(y => y.itemGroupCode == EnumSalaryGroup.Gross && y.ItemCode == EnumSalaryItemCode.Allowance && y.ItemID == oAttnSpacialAllowance.ID)) { if (oEmpDailAttnProcesses == null) oEmpDailAttnProcesses = oAttnProcesses.Where(x => x.EmployeeID == sMonthly.EmployeeID).ToList(); double OTHour = 0; var tfshifts = oShifts.FindAll(x => x.SpecialAllowanceID != null); List oShiftIDs = tfshifts.Select(a => a.ID).ToList(); //List oShiftIDs = sMonthly.GradeSalaries.SelectMany(x => x.ADParameters).Where(y => y.AllowDeductID == //oAttnSpacialAllowance.ID).SelectMany(z => z.ADParameterShifts).Select(a => a.ShiftID.Integer).ToList(); OTHour = oEmpDailAttnProcesses.Where(x => x.ShiftID != null && oShiftIDs.Contains((int)x.ShiftID) && x.AttenType != EnumAttendanceType.Absent && x.AttenType != EnumAttendanceType.Holiday && x.AttenType != EnumAttendanceType.Leave && x.AttenType != EnumAttendanceType.WeeklyHoliday) .Count(); List oMonthlyDetails = sMonthly.Details.Where(y => y.itemGroupCode == EnumSalaryGroup.Gross && y.ItemCode == EnumSalaryItemCode.Allowance && y.ItemID == oAttnSpacialAllowance.ID).ToList(); //UndoProrated(sMonthly, oMonthlyDetails); ADParameter param = sMonthly.GradeSalaries.SelectMany(x => x.ADParameters).Where(y => y.AllowDeductID == oAttnSpacialAllowance.ID).FirstOrDefault(); // double nRate = Math.Round((sMonthly.ThisMonthBasic / 208) * (200 / 100.00), 2) * param.OTTimes; double nRate = Math.Round((sMonthly.ThisMonthBasic / 208) * (200 / 100.00), 2) * 2; //if (OTHour > 0) //{ foreach (SalaryMonthlyDetail smDetail in oMonthlyDetails) { smDetail.ChangedAmount = Math.Round(nRate * OTHour); smDetail.ChangedAmount = smDetail.ChangedAmount; smDetail.CalculatedAmount = smDetail.CalculatedAmount; scalculator.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Special_Allowance_Days, oAttnSpacialAllowance.ID, oAttnSpacialAllowance.ID, Convert.ToString(EnumSalaryItemCode.Special_Allowance_Days).Replace('_', ' '), OTHour); scalculator.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Special_Allowance_Rate, oAttnSpacialAllowance.ID, oAttnSpacialAllowance.ID, Convert.ToString(EnumSalaryItemCode.Special_Allowance_Rate).Replace('_', ' '), nRate != 0 ? nRate : 0); } // } } #endregion if (smTempDetails.Count > 0) sMonthly.Details.AddRange(smTempDetails); } #endregion } } catch(Exception ex) { throw new Exception(ex.Message); } #endregion } private static void UndoProrated(SalaryMonthly sMonthly, List oMonthlyDetails) { foreach (var item in oMonthlyDetails) { double changedAmount = 0, calcullatedAmount = 0; foreach (EmployeeGradeSalary gItem in sMonthly.GradeSalaries.Where(x => x.ArrearType == EnumArrearType.NotPresent)) { if (gItem.FractionofFromTo != 0) { changedAmount += item.ChangedAmount / gItem.FractionofFromTo; calcullatedAmount += item.CalculatedAmount / gItem.FractionofFromTo; } } item.ChangedAmount = changedAmount; item.CalculatedAmount = calcullatedAmount; } } } }