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; using System.Collections; namespace Payroll.BO { 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 } [Serializable] public class SalaryCalculator : SalaryException { #region Define Class Veriable private ObjectsTemplate _employees; private ObjectsTemplate _allowdeducitons; private ObjectsTemplate _processItems; private ObjectsTemplate _salaryMonthlys; private List _processStatuses; private ObjectsTemplate _PrvMonthsalary; private ObjectsTemplate _adParameters; private ObjectsTemplate _objDailyAttnProcess; public DateTime _processMonth; public int _nYear; public event ProcessStatus ProcessStatus; public event ProgressStatus ProgressStatus; ObjectsTemplate _workingHours; #endregion Define Class Veriable public bool _isDesignationFromDescriptionText; public ObjectsTemplate SalaryMonthlies { get { return _salaryMonthlys; } } public SalaryCalculator(ObjectsTemplate ProcessItems) { _processItems = ProcessItems; } public SalaryCalculator() { _processItems = ProcessItem.Get(); } public List ErrorList { get { return _processStatuses; } } private void UpdateprocessStatus(string statusString) { if (ProcessStatus != null) ProcessStatus(statusString); } private void UpdateProgressStatus(EnumProcessStatus status) { if (ProgressStatus != null) ProgressStatus(status); } public ObjectsTemplate Employees { get { return _employees; } } public void FixAmount() { List oEmps = Employee.GetAllEmps(); foreach (SalaryMonthly sm in this._salaryMonthlys) { Employee emp = oEmps.Find(x => x.ID == sm.EmployeeID); double nAmount = 0; double nBasicAmount = 0; int nCount = 0; double nOtherAmount = 0; double nFinalAmount = 0; double arrearamount = 0; if (emp != null) { foreach (SalaryMonthlyDetail smd in sm.Details) { smd.ChangedAmount = Math.Round(smd.ChangedAmount); smd.CalculatedAmount = smd.ChangedAmount; if (smd.itemGroupCode != EnumSalaryGroup.Arrear) { if ((smd.ItemCode == EnumSalaryItemCode.Basic_Salary && smd.ItemID == -101) || (smd.ItemCode == EnumSalaryItemCode.Allowance && smd.ItemID == 1) || (smd.ItemCode == EnumSalaryItemCode.Allowance && smd.ItemID == 2) || (smd.ItemCode == EnumSalaryItemCode.Allowance && smd.ItemID == 3)) { nAmount += smd.ChangedAmount; } if (smd.ItemCode == EnumSalaryItemCode.Basic_Salary && smd.ItemID == -101) { nBasicAmount = smd.ChangedAmount; nCount++; } } else { if ((smd.ItemCode == EnumSalaryItemCode.Basic_Salary && smd.ItemID == -101) || (smd.ItemCode == EnumSalaryItemCode.Allowance && smd.ItemID == 1) || (smd.ItemCode == EnumSalaryItemCode.Allowance && smd.ItemID == 2) || (smd.ItemCode == EnumSalaryItemCode.Allowance && smd.ItemID == 3)) { arrearamount += smd.ChangedAmount; } } } double nDiff = 0; if (nBasicAmount < emp.BasicSalary) continue; if (nCount < 2) nDiff = emp.GrossSalary - nAmount; SalaryMonthlyDetail det = sm.Details.Find(x => x.ItemCode == EnumSalaryItemCode.Allowance && x.ItemID == 10); if (det != null) { //if (nDiff > 0) //{ det.ChangedAmount = nDiff; det.CalculatedAmount = nDiff; nOtherAmount = det.CalculatedAmount; //} //else //{ // det.ChangedAmount -= Math.Abs(nDiff); //} } } if (sm.ArrearGradeSalaries.Count > 0) { foreach (EmployeeGradeSalary gs in sm.ArrearGradeSalaries) { double lastmonthgross = gs.GrossSalary; nFinalAmount = lastmonthgross - arrearamount; this.AddDetail(sm, EnumSalaryGroup.Arrear, EnumSalaryItemCode.Allowance, 10, 4, "Other Allowance", GlobalFunctions.Round(nFinalAmount)); } } } } public void Process(ObjectsTemplate employees, DateTime processMonth, int nYear) { //SalaryException oSException = new SalaryException(); _employees = employees; _processMonth = processMonth; _nYear = nYear; 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(); if (Payroll.BO.SystemInformation.CurrentSysInfo.PayrollTypeID.Integer != 2) { UpdateprocessStatus("Calculating PF & CPF...."); this.PF(); } this.OverTimeArrearProcess(); //UpdateprocessStatus("Calculating Employees Income tax...."); UpdateprocessStatus("Calculating Income Tax"); this.FixAmount(); this.Tax(); UpdateprocessStatus("Calculating Cost-Center"); this.PrepareCostcenterData(); UpdateprocessStatus("Calculating Loan Installment"); this.LoanProcess(); UpdateprocessStatus("Calculating Net Income"); this.NetIncome(); UpdateprocessStatus("Calculating Attendance Days"); this.AttendanceDayProcess(); UpdateprocessStatus("Calculating Leave Days"); this.LeaveDayProcess(); UpdateprocessStatus("Calculating Salary Exception"); this.SalaryExceptionCalculation(this); UpdateprocessStatus(""); //this.LeavePrepare(oSException.GetEmpLeaveStatus()); } private void Initialize() { _processStatuses = new List(); _salaryMonthlys = new ObjectsTemplate(); _PrvMonthsalary = SalaryMonthly.Get(GlobalFunctions.LastDateOfMonth(_processMonth.AddMonths(-1))); } private bool ProcessStartValidation() { return false; } private void AddEmployeeToProcess() { UpdateProgressStatus(EnumProcessStatus.Start); ObjectsTemplate empCostCenters = EmployeeCostCenter.Get(); ObjectsTemplate categories = Category.Get(); ObjectsTemplate departments = Department.Get(); _isDesignationFromDescriptionText = ConfigurationManager.GetBoolValue("designation", "desigfromdescriptiontext", EnumConfigurationType.Logic); foreach (Employee employee in _employees) { UpdateProgressStatus(EnumProcessStatus.PerformStep); this.UpdateprocessStatus(" Collecting information for the employee " + employee.Name + " ( " + employee.EmployeeNo + ")"); SalaryMonthly salary = new SalaryMonthly(); salary.EmployeeID = employee.ID; salary.EmployeeNo = employee.EmployeeNo; salary.CategoryID = employee.CategoryID; if (employee.CategoryID == null) { AddProcessStatus(employee, "Category not yet assingned"); } else { salary.Category = categories.Find(delegate(Category detail) { return (detail.ID.Integer == employee.CategoryID.Integer); }); } salary.Gender = employee.Gender; salary.SalaryMonth = _processMonth; if (employee.GradeID.IsUnassigned == true) AddProcessStatus(employee, "grade not yet assingned"); else salary.GradeID = employee.GradeID; if (employee.DepartmentID.IsUnassigned == true) AddProcessStatus(employee, "Department not yet assingned"); // else if (departments.FirstOrDefault(o => o.ID == employee.DepartmentID).RCCode == "") AddProcessStatus(employee, "RC Code missing in Department"); else salary.DepartmentID = employee.DepartmentID; string rccode = ""; if (salary.DepartmentID == null) salary.RCCode = ""; else { Department dep = departments.Find(x => x.ID == salary.DepartmentID); salary.RCCode= GlobalFunctions.FindRCCode2(dep, departments); if(salary.RCCode=="") AddProcessStatus(employee, "RC Code missing in Department"); } if (_isDesignationFromDescriptionText) { if (employee.DescriptionText == "") AddProcessStatus(employee, "Designation not yet assingned"); } else { if (employee.DesignationID.IsUnassigned == true) AddProcessStatus(employee, "Designation not yet assingned"); else salary.DesignationID = employee.DesignationID; } if (employee.LocationID.IsUnassigned) AddProcessStatus(employee, "Loacation not yet assingned"); else salary.LocationID = employee.LocationID; salary.DesignationID = employee.DesignationID; salary.DesignationText = employee.DescriptionText; if (employee.PaymentMode == EnumPaymentMode.BankTransfer) { if (employee.BranchID == null || employee.BranchID.IsUnassigned) AddProcessStatus(employee, "Employee payment mode is diclared" + " to bank transfer, but no bank/account information found"); else { salary.BranchID = 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; 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." + " "); } bool bfixedAmount = ConfigurationManager.GetBoolValue("costcenter", "manadatoryinsalary", EnumConfigurationType.Logic); if (bfixedAmount == true) { ObjectsTemplate empinvolments = EmployeeCostCenter.Get(empCostCenters, salary.EmployeeID); if (empinvolments == null || empinvolments.Count == 0) AddProcessStatus(employee, "Cost-Center not yet assingned"); } _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) { if (detail.itemGroupCode == EnumSalaryGroup.Gross || detail.itemGroupCode == EnumSalaryGroup.Arrear) { netAmount = netAmount + detail.ChangedAmount; sPosItems = sPosItems + detail.Description + ":" + detail.ChangedAmount.ToString() + ", "; } else if (detail.itemGroupCode == EnumSalaryGroup.Deductions || detail.itemGroupCode == EnumSalaryGroup.UnauthLeave) { netAmount = netAmount - detail.ChangedAmount; sNegItems = sNegItems + detail.Description + ":" + 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 Zero or less than 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.Find(delegate(ProcessItem item) { return item.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 = new SalaryMonthlyDetail(); detail.ItemID = itemId; detail.itemGroupCode = group; detail.ItemCode = itemcode; detail.SupportID = ID.FromInteger(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); 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 BasicSalary() { UpdateProgressStatus(EnumProcessStatus.Start); //GetCurrentMonthSalaryItems function return current month's employee grade, salary and effect date. //effect date must sorted, otherwise error will be generated from next function. #region Calculate Normal Salary ObjectsTemplate gradeSalaryItems = EmployeeGradeSalary.Service.GetCurrMonthSalaryItems(SystemInformation.CurrentSysInfo.NextPayProcessDate); double basicSalary = 0; SalaryMonthlyDetail basicDetail = null; if (_workingHours == null) _workingHours = MonthlyWorkingHour.Get(_processMonth); #region Remove Employee from salary process if (Payroll.BO.SystemInformation.CurrentSysInfo.PayrollTypeID.Integer == 2) { List osals = new List(); foreach (SalaryMonthly salary in _salaryMonthlys) { MonthlyWorkingHour whour = _workingHours.Find(delegate(MonthlyWorkingHour wh) { return (wh.EmployeeID.Integer == salary.EmployeeID.Integer); }); if (whour == null) { osals.Add(salary); } else if (whour.RegularHour == 0) { osals.Add(salary); } } foreach (SalaryMonthly salary in osals) { _salaryMonthlys.Remove(salary); } } #endregion foreach (SalaryMonthly salary in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); //salary.GradeSalaries = EmployeeGradeSalary.Get(gradeSalaryItems, salary.EmployeeID); salary.GradeSalaries = gradeSalaryItems.FindAll(x => x.EmployeeID == salary.EmployeeID).ToObjectsTemplate(); if (salary.GradeSalaries.Count == 0) continue; if (salary.Category.WagesType != EnumWagesType.Monthly) { foreach (EmployeeGradeSalary esal in salary.GradeSalaries) { MonthlyWorkingHour whour = _workingHours.Find(wh => wh.EmployeeID.Integer == salary.EmployeeID.Integer); if (whour != null) { esal.BasicSalary = esal.BasicSalary * whour.RegularHour; } esal.ActualBasicSalary = esal.BasicSalary; } } EmployeeGradeSalary.PrepareDataForCurrentSalary(salary.Employee, salary.GradeSalaries); basicSalary = 0; if (salary.Category.WagesType != EnumWagesType.Monthly) { if (_workingHours == null) _workingHours = MonthlyWorkingHour.Get(_processMonth); salary.ThisMonthBasic = salary.Employee.BasicSalary; MonthlyWorkingHour whour = _workingHours.Find(delegate(MonthlyWorkingHour wh) { return (wh.EmployeeID.Integer == salary.EmployeeID.Integer); }); if (whour != null) { salary.HoursOrDaysNDF = whour.RegularHour; basicSalary = salary.ThisMonthBasic * whour.RegularHour; } else basicSalary = salary.ThisMonthBasic; } else { basicSalary = 0; //salary.GradeSalaries[0].FractionofFromTo = 1; // for redisha back process if (salary.GradeSalaries.Count > 0) { salary.ThisMonthBasic = salary.GradeSalaries[salary.GradeSalaries.Count - 1].BasicSalary; salary.ThisMonthBasic = salary.ThisMonthBasic; salary.ThisMonthGross = salary.GradeSalaries[salary.GradeSalaries.Count - 1].GrossSalary; salary.ThisMonthGross = salary.ThisMonthGross; } foreach (EmployeeGradeSalary item in salary.GradeSalaries) { item.BasicSalary = item.BasicSalary * item.FractionofFromTo; item.BasicSalary =item.BasicSalary; item.GrossSalary = item.GrossSalary * item.FractionofFromTo; item.GrossSalary = item.GrossSalary; basicSalary = basicSalary + item.BasicSalary; } } basicDetail = this.AddDetail(salary, EnumSalaryGroup.Gross, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, 0, "Basic",basicSalary); if (salary.PayrollTypeID.Integer == (int)EnumPayrollType.Appentis) { basicDetail.Description = "Allowance"; } } #endregion Calculate Normal Salary #region calculate arrear amount double arrearAmount = 0; if (Payroll.BO.SystemInformation.CurrentSysInfo.PayrollTypeID.Integer == 1) { ObjectsTemplate arrearItems = EmployeeGradeSalary.Service.GetArrearItems(); foreach (SalaryMonthly salary in _salaryMonthlys) { arrearAmount = 0; salary.ArrearGradeSalaries = EmployeeGradeSalary.Get(arrearItems, 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) - salary.GetAmountOnRange(salary.Employee, arrearItem.EffectDate, (DateTime)arrearItem.TillDate, EnumSalaryGroup.Gross, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, arrearItem, null); arrearAmount = arrearAmount - salary.GetUnAuthorizeAmount(arrearItem.BasicSalary, salary.Employee, arrearItem.EffectDate, (DateTime)arrearItem.TillDate, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary); arrearAmount = GlobalFunctions.Round(arrearAmount); } if (salary.ArrearGradeSalaries.Count > 0) { DateTime arrearPaidFrom = salary.ArrearGradeSalaries[0].EffectDate; salary.ArrearPaidGradeSalaries = EmployeeGradeSalary.Service.GetArrearPaidItems(salary.EmployeeID, arrearPaidFrom); // salary.ArrearPaidGradeSalaries = gradeSalaryItems.FindAll(x => x.EmployeeID == salary.EmployeeID && x.TillDate >= arrearPaidFrom && x.ArrearType == EnumArrearType.Paid).ToObjectsTemplate(); //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); SalaryMonthlyDetail odtail = SalaryMonthly.Service.GetDetail(salary.EmployeeID, GlobalFunctions.LastDateOfMonth(((DateTime)paidarrearItem.TillDate).AddMonths(1)), EnumSalaryGroup.Arrear, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary); double paidAmount = 0; if (odtail != null) { if (salary.ArrearPaidGradeSalaries[0].EffectDate < arrearPaidFrom) paidAmount = (odtail.ChangedAmount * GlobalFunctions.GetFraction(arrearPaidFrom, (DateTime)paidarrearItem.TillDate)) / GlobalFunctions.GetFraction(paidarrearItem.EffectDate, (DateTime)paidarrearItem.TillDate); else paidAmount = odtail.ChangedAmount; } //arrearAmount = arrearAmount - (salary.GetAmountOnRange(salary.Employee, paidarrearItem.EffectDate, (DateTime)paidarrearItem.TillDate, EnumSalaryGroup.Arrear, // EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary)); arrearAmount = GlobalFunctions.Round(arrearAmount) - GlobalFunctions.Round(paidAmount); } if (arrearAmount != 0) { SalaryMonthlyDetail detail = this.AddDetail(salary, EnumSalaryGroup.Arrear, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, 0, "Basic", GlobalFunctions.Round(arrearAmount)); detail.Position = basicDetail.Position; } } } } #endregion calculate arrear amount UpdateProgressStatus(EnumProcessStatus.End); } private void PF() { int nn = 1; UpdateProgressStatus(EnumProcessStatus.Start); try { bool earnedBasic = ConfigurationManager.GetBoolValue("pf", "earnedbasic", EnumConfigurationType.Logic); //bool earnedBasic = true; double pfPercent = (SystemInformation.CurrentSysInfo.pFContriCompany / 100); List oPfExceptions = PFException.Get(); foreach (SalaryMonthly salary in _salaryMonthlys) { //if (nn == 143) // nn = 143; UpdateProgressStatus(EnumProcessStatus.PerformStep); if (salary.Employee.CategoryID.Integer != 1) continue; SalaryMonthlyDetail pfDetail = null; pfDetail = this.AddDetail(salary, EnumSalaryGroup.Deductions, EnumSalaryItemCode.PF_Contribution, (int)EnumSalaryItemCode.PF_Contribution, 0, "PF", 0); SalaryMonthlyDetail basic = salary.Details.Find(delegate(SalaryMonthlyDetail detail) { return (detail.ItemCode == EnumSalaryItemCode.Basic_Salary && detail.itemGroupCode == EnumSalaryGroup.Gross); }); SalaryMonthlyDetail basicarrear = salary.Details.Find(delegate(SalaryMonthlyDetail detail) { return (detail.ItemCode == EnumSalaryItemCode.Basic_Salary && detail.itemGroupCode == EnumSalaryGroup.Arrear); }); if (basic == null) continue; if (basicarrear == null) basicarrear = new SalaryMonthlyDetail(); if (salary.Employee.PFMemberType == EnumPFMembershipType.Live) { if (salary.Employee.PFMemberShiptDate >= GlobalExtensions.FirstDateOfMonth(SystemInformation.CurrentSysInfo.NextPayProcessDate)) { pfDetail.CalculatedAmount = (((basic.CalculatedAmount * GlobalFunctions.GetFraction(salary.Employee.PFMemberShiptDate, SystemInformation.CurrentSysInfo.NextPayProcessDate)))); } else { pfDetail.CalculatedAmount = basic.CalculatedAmount; } //else //{ // if ((_PrvMonthsalary.Exists(x => x.EmployeeID.Integer == salary.EmployeeID.Integer && x.PFMembershipType == EnumPFMembershipType.Live) == true)) // { // pfDetail.CalculatedAmount = (basic.ChangedAmount + basicarrear.ChangedAmount) * pfPercent; // } // else // { // if (salary.ArrearGradeSalaries.Count == 0) // { // pfDetail.CalculatedAmount = basic.ChangedAmount; // if (basicarrear != null) pfDetail.CalculatedAmount = pfDetail.CalculatedAmount + basicarrear.ChangedAmount; // pfDetail.CalculatedAmount = pfDetail.CalculatedAmount * pfPercent; // } // else // { // if (salary.ArrearGradeSalaries[0].EffectDate <= salary.Employee.PFMemberShiptDate) // { // double pfarrear = salary.ArrearGradeSalaries[0].BasicSalary * GlobalFunctions.GetFraction(salary.Employee.PFMemberShiptDate, (DateTime) // salary.ArrearGradeSalaries[salary.ArrearGradeSalaries.Count - 1].TillDate); // pfDetail.CalculatedAmount = (basic.ChangedAmount + pfarrear) * pfPercent; ; // } // else // { // EmployeeGradeSalary gradesl = EmployeeGradeSalary.GetBasicOnDate(salary.EmployeeID, salary.Employee.PFMemberShiptDate); // if (gradesl == null) continue; // double pfarrear = basic.CalculatedAmount + gradesl.BasicSalary * GlobalFunctions.GetFraction(salary.Employee.PFMemberShiptDate, (DateTime) // salary.ArrearGradeSalaries[salary.ArrearGradeSalaries.Count - 1].TillDate); // pfDetail.CalculatedAmount = pfarrear * pfPercent; // } // } // } //} // pfDetail.ChangedAmount = pfDetail.CalculatedAmount; if (salary.Employee.PFMemberType != EnumPFMembershipType.Live) continue; if (earnedBasic == false) { //pfDetail = this.AddDetail(salary, EnumSalaryGroup.Deductions, //EnumSalaryItemCode.PF_Contribution, (int)EnumSalaryItemCode.PF_Contribution, 0, "PF", GlobalFunctions.Round(salary.ThisMonthBasic * pfPercent)); } else { if (basic != null && pfDetail != null) { pfDetail.CalculatedAmount = GlobalFunctions.Round(pfDetail.CalculatedAmount * pfPercent); } //if (basic != null && pfDetail==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.GetDetail(EnumSalaryGroup.UnauthLeave, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary); if (basic != null) { pfDetail.CalculatedAmount = pfDetail.CalculatedAmount - GlobalFunctions.Round(basic.CalculatedAmount * pfPercent); } if (basicarrear != null) { pfDetail.CalculatedAmount = pfDetail.CalculatedAmount + GlobalFunctions.Round(basicarrear.CalculatedAmount * pfPercent); } if (pfDetail != null) pfDetail.ChangedAmount = pfDetail.CalculatedAmount; } #region Exception PF //PFException oEmpPFException = oPfExceptions.FirstOrDefault(x => x.EmployeeID == salary.Employee.ID); //if (oEmpPFException != null) // && oEmpPFException.StartDate <= salary.SalaryMonth) //{ // if (pfDetail != null) // { // pfDetail.CalculatedAmount = oEmpPFException.EPFPercent == 0 ? oEmpPFException.EPFAmount : GlobalFunctions.Round(salary.ThisMonthBasic * (oEmpPFException.EPFPercent / 100)); // pfDetail.ChangedAmount = pfDetail.CalculatedAmount; // } //} #endregion } UpdateProgressStatus(EnumProcessStatus.End); nn++; } } catch (Exception exp) { throw new Exception(exp.Message); } } private void AllowanceDeduction() { UpdateProgressStatus(EnumProcessStatus.Start); _allowdeducitons = Payroll.BO.AllowanceDeduction.Get(EnumStatus.Regardless); _adParameters = ADParameter.Get(EnumStatus.Active); if (_adParameters == null || _adParameters.Count == 0) { return; } ObjectsTemplate indvAllowances = ADParameterEmployee.Get( GlobalFunctions.FirstDateOfMonth(_processMonth), GlobalFunctions.LastDateOfMonth(_processMonth)); foreach (SalaryMonthly salary in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); ADParameter.ApplicableParameters(salary.Employee, salary, _adParameters); this.GradeDefinedAllowDeduct(salary, salary.GradeSalaries, EnumSalaryGroup.Gross, indvAllowances, EnumSide.Add); if (Payroll.BO.SystemInformation.CurrentSysInfo.PayrollTypeID.Integer != 2) { this.GradeDefinedAllowDeduct(salary, salary.ArrearGradeSalaries, EnumSalaryGroup.Arrear, indvAllowances, EnumSide.Add); } // this.GradeDefinedAllowDeduct(salary, salary.ArrearPaidGradeSalaries, EnumSalaryGroup.Arrear, indvAllowances, EnumSide.Deduct); this.IndividualAllowDeduct(salary, indvAllowances); } } private void IndividualAllowDeduct(SalaryMonthly salary, ObjectsTemplate indvAllowances) { double amount = 0; EnumSalaryGroup groupCode = EnumSalaryGroup.Gross; #region Individual Allowance List items = indvAllowances.FindAll(delegate(ADParameterEmployee item) { return item.EmployeeID.Integer == salary.Employee.ID.Integer && item.ADEmpType == EnumADEmpType.AppliedToIndividual; }); foreach (ADParameterEmployee item in items) { amount = 0; ADParameter parameter = _adParameters.GetItem(item.ADParameterID); amount = parameter.GetIndividualAmount(salary.Employee, _processMonth, item, salary.Employee.GrossSalary, salary.GetGrossAmount(EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary), salary); 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 - salary.GetUnAuthorizeAmount(amount, salary.Employee, item.FormDate, (DateTime)item.TillDate, itemCode, parameter.AllowDeductID.Integer); EnumSalaryGroup arrgCode = (parameter.AllowanceDeduction.AllowOrDeductType == EnumAllowOrDeduct.Allowance) ? EnumSalaryGroup.Gross : EnumSalaryGroup.Deductions; amount = amount - salary.GetAmountOnRange(salary.Employee, item.FormDate, (DateTime)item.TillDate, arrgCode, itemCode, parameter.AllowDeductID.Integer, parameter.ID.Integer); if (amount == 0) continue; } //if (parameter.AllowanceDeduction.Code == "027") // amount = amount * 6; SalaryMonthlyDetail detail = salary.GetDetail(groupCode, itemCode, parameter.AllowDeductID.Integer); if (detail == null) detail = this.AddDetail(salary, groupCode, itemCode, parameter.AllowDeductID.Integer, parameter.ID.Integer, 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; } detail.Position = item.AllowDeduct.Sequence + 1; } #endregion Individual Allowance } private void GradeDefinedAllowDeduct(SalaryMonthly salary, ObjectsTemplate gradeSalaries, EnumSalaryGroup gCode, ObjectsTemplate 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.GetItem(parameter.AllowDeductID); if (parameter.AllowanceDeduction.AllowOrDeductType == EnumAllowOrDeduct.Deduction && GroupCode == EnumSalaryGroup.Gross) GroupCode = EnumSalaryGroup.Deductions; amount = 0; if (parameter.EntitleType == EnumEntitleType.Grade) { if (salary.Category.WagesType != EnumWagesType.Monthly) { empGradeSalary.FractionofFromTo = 1; amount = parameter.GetGradeDefinedAmount(salary.Employee, empGradeSalary.BasicSalary, empGradeSalary.GrossSalary, empGradeSalary); int nonRegularSpecialAllow = ConfigurationManager.GetIntValue("adparameter", "specialallowance", EnumConfigurationType.Logic); if (nonRegularSpecialAllow == parameter.ID.Integer) { MonthlyWorkingHour whour = _workingHours.Find(delegate(MonthlyWorkingHour wh) { return (wh.EmployeeID.Integer == salary.EmployeeID.Integer); }); if (whour != null) { double nActualBasic = amount * whour.SpecialHour; amount = nActualBasic; } } } else { amount = parameter.GetGradeDefinedAmount(salary.Employee, empGradeSalary.BasicSalary, empGradeSalary.GrossSalary, empGradeSalary); } } else continue; //if (parameter.IsFlatAmount == true) // amount = amount + parameter.FlatAmount * empGradeSalary.FractionofFromTo; //if (parameter.IsFlatAmount == true) amount = amount * empGradeSalary.FractionofFromTo; EnumSalaryItemCode itemCode = (parameter.AllowOrDeductType == EnumAllowOrDeduct.Allowance) ? EnumSalaryItemCode.Allowance : EnumSalaryItemCode.Deduction; if (GroupCode == EnumSalaryGroup.Arrear && salary.PayrollTypeID.Integer != 2) { amount = amount - salary.GetUnAuthorizeAmount(amount, salary.Employee, empGradeSalary.EffectDate, (DateTime)empGradeSalary.TillDate, itemCode, parameter.AllowDeductID.Integer); EnumSalaryGroup arrgCode = (parameter.AllowanceDeduction.AllowOrDeductType == EnumAllowOrDeduct.Allowance) ? EnumSalaryGroup.Gross : EnumSalaryGroup.Deductions; amount = amount - salary.GetAmountOnRange(salary.Employee, empGradeSalary.EffectDate, (DateTime)empGradeSalary.TillDate, arrgCode, itemCode, parameter.AllowDeductID.Integer, parameter.ID.Integer, empGradeSalary, parameter); foreach (EmployeeGradeSalary paidarrearItem in salary.ArrearPaidGradeSalaries) { SalaryMonthlyDetail odtail = SalaryMonthly.Service.GetDetail(salary.EmployeeID, GlobalFunctions.LastDateOfMonth(((DateTime)paidarrearItem.TillDate).AddMonths(1)), EnumSalaryGroup.Arrear, itemCode, parameter.AllowDeductID.Integer); double paidAmount = 0; if (odtail != null) { if (salary.ArrearPaidGradeSalaries[0].EffectDate < empGradeSalary.EffectDate) paidAmount = (odtail.ChangedAmount * GlobalFunctions.GetFraction(empGradeSalary.EffectDate, (DateTime)paidarrearItem.TillDate)) / GlobalFunctions.GetFraction(paidarrearItem.EffectDate, (DateTime)paidarrearItem.TillDate); else paidAmount = odtail.ChangedAmount; } //arrearAmount = arrearAmount - (salary.GetAmountOnRange(salary.Employee, paidarrearItem.EffectDate, (DateTime)paidarrearItem.TillDate, EnumSalaryGroup.Arrear, // EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary)); amount = GlobalFunctions.Round(amount) - GlobalFunctions.Round(paidAmount); } if (amount == 0) continue; } if (GroupCode == EnumSalaryGroup.Arrear && side == EnumSide.Deduct) amount = -amount; SalaryMonthlyDetail detail = salary.GetDetail(GroupCode, itemCode, parameter.AllowDeductID.Integer); if (amount == 1) amount = 0; if (detail == null) detail = this.AddDetail(salary, GroupCode, itemCode, parameter.AllowDeductID.Integer, parameter.ID.Integer, parameter.AllowanceDeduction.Name, amount); else { detail.CalculatedAmount = detail.CalculatedAmount + amount; detail.CalculatedAmount = GlobalFunctions.Round(detail.CalculatedAmount); detail.ChangedAmount = detail.CalculatedAmount; detail.SupportID = parameter.ID; } detail.Position = parameter.AllowanceDeduction.Sequence + 1; } } } private void OverTimeProcess() { UpdateProgressStatus(EnumProcessStatus.Start); TermParameter ob = new TermParameter(); Term shiftWiseOTime = null; ObjectsTemplate _shiftWiseOTimes = Term.Get(EnumStatus.Active); shiftWiseOTime = _shiftWiseOTimes.Where(o => o.EntityMode == EnumEntityMode.ShiftAllowance).FirstOrDefault(); ObjectsTemplate otProcess = OTProcess.Get(SystemInformation.CurrentSysInfo.NextPayProcessDate); if (otProcess == null || otProcess.Count == 0) return; foreach (SalaryMonthly sMonthly in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); List empOTProcess = otProcess.Where(o => o.EmployeeID == sMonthly.EmployeeID && o.TermObj.EntityMode != EnumEntityMode.ShiftAllowance).ToObjectsTemplate(); List empOTShift = otProcess.Where(o => o.EmployeeID == sMonthly.EmployeeID && o.TermObj.EntityMode == EnumEntityMode.ShiftAllowance).OrderBy(z => z.OTMonth).ToObjectsTemplate(); List datesOTProcess = new List(); List datesOTShift = new List(); datesOTProcess = empOTProcess.Select(x => x.OTMonth).Distinct().ToList(); datesOTShift = empOTShift.Select(x => x.OTMonth).Distinct().ToList(); if (empOTProcess != null) { //foreach (DateTime dt in datesOTProcess) //{ // OTProcess pros = empOTProcess.Find(x => x.OTMonth == dt); //} foreach (OTProcess process in empOTProcess) { //this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Over_Time_Hours, process.TermID.Integer, process.TermParameterID.Integer, process.TermObj.Name + "-" + process.OTMonth.ToString("MMM yyyy") + " hour", process.TotalHour); this.AddDetail(sMonthly, EnumSalaryGroup.Gross, EnumSalaryItemCode.Over_Time_Amount, process.TermID.Integer, process.TermParameterID.Integer, process.TermObj.Name + "-" + process.OTMonth.ToString("MMM yyyy"), GlobalFunctions.Round(process.Amount)); } } if (empOTShift != null) { foreach (DateTime dt in datesOTShift) { double totalOTAmount = 0; string description = ""; string shortCode = ""; int count = 0; List empOTShift2 = empOTShift.FindAll(x => x.OTMonth == dt).ToObjectsTemplate(); foreach (OTProcess process in empOTShift2) { count++; if (process.TermObj.Code == "005") shortCode = "E"; else if (process.TermObj.Code == "006") shortCode = "N"; else shortCode = "SW"; description += shortCode + " - " + process.TotalHour.ToString() + ","; totalOTAmount += process.Amount; if (count == empOTShift2.Count) { description = description.Trim(','); description = "(" + description + ")"; if (totalOTAmount > shiftWiseOTime.MaxValue) totalOTAmount = shiftWiseOTime.MaxValue; this.AddDetail(sMonthly, EnumSalaryGroup.Gross, EnumSalaryItemCode.Over_Time_Amount, process.TermID.Integer, process.TermParameterID.Integer, "Shift Allowance " + process.OTMonth.ToString("MMM yyyy") + description, GlobalFunctions.Round(totalOTAmount)); } } } } } UpdateProgressStatus(EnumProcessStatus.End); } private void AttendanceDayProcess() { UpdateProgressStatus(EnumProcessStatus.Start); // TermParameter ob = new TermParameter(); DateTime FirstDateOfMonth = SystemInformation.CurrentSysInfo.NextPayProcessDate.FirstDateOfMonth().Date; DateTime LastDateOfMonth = SystemInformation.CurrentSysInfo.NextPayProcessDate.LastDateOfMonth().Date; int TotalDaysInMonth = SystemInformation.CurrentSysInfo.NextPayProcessDate.TotalDaysInMonth(); List attnProcess = DailyAttnProcess.Get().Where(x => x.AttnDate >= FirstDateOfMonth && x.AttnDate <= LastDateOfMonth).ToList(); if (attnProcess == null || attnProcess.Count == 0) { UpdateProgressStatus(EnumProcessStatus.End); return; } foreach (SalaryMonthly sMonthly in _salaryMonthlys) { DateTime joiningDate = DateTime.MinValue; Employee oEmployee = _employees.FirstOrDefault(x => x.ID.Integer == sMonthly.EmployeeID.Integer); if (oEmployee != null) joiningDate = oEmployee.JoiningDate; UpdateProgressStatus(EnumProcessStatus.PerformStep); if (joiningDate < FirstDateOfMonth) { this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Total_Days, (int)EnumSalaryItemCode.Total_Days, 0, "Working Days", TotalDaysInMonth); } else if (joiningDate > LastDateOfMonth) { this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Total_Days, (int)EnumSalaryItemCode.Total_Days, 0, "Working Days", 0); } else { this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Total_Days, (int)EnumSalaryItemCode.Total_Days, 0, "Working Days", (LastDateOfMonth.Subtract(joiningDate).TotalDays + 1)); } List empAttnProcess = attnProcess.Where(x => x.EmployeeID.Integer == sMonthly.EmployeeID.Integer).ToList(); if (empAttnProcess != null && empAttnProcess.Count > 0) { if (empAttnProcess.Any(x => x.AttenType == EnumAttendanceType.Present || x.AttenType == EnumAttendanceType.Late || x.AttenType == EnumAttendanceType.Delay)) this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Tot_Attend_Days, (int)EnumSalaryItemCode.Tot_Attend_Days, 0, "Present Days", empAttnProcess.Where(x => x.AttenType == EnumAttendanceType.Present || x.AttenType == EnumAttendanceType.Late || x.AttenType == EnumAttendanceType.Delay).Count()); if (empAttnProcess.Any(x => x.AttenType == EnumAttendanceType.WeeklyHoliday || x.AttenType == EnumAttendanceType.Holiday)) this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Total_HoliDays, (int)EnumSalaryItemCode.Total_HoliDays, 0, "Holidays", empAttnProcess.Where(x => x.AttenType == EnumAttendanceType.WeeklyHoliday || x.AttenType == EnumAttendanceType.Holiday).Count()); //if (empAttnProcess.Any(x => x.AttenType == EnumAttendanceType.Absent)) // this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Tot_UnauthLeave_Days, 1, 0, "Absent Days", empAttnProcess.Where(x => x.AttenType == EnumAttendanceType.Absent).Count()); if (empAttnProcess.Any(x => x.AttenType == EnumAttendanceType.Delay)) this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Delay_Days, (int)EnumSalaryItemCode.Delay_Days, 0, "Delay Days", empAttnProcess.Where(x => x.AttenType == EnumAttendanceType.Delay).Count()); } } UpdateProgressStatus(EnumProcessStatus.End); } private void LeaveDayProcess() { UpdateProgressStatus(EnumProcessStatus.Start); // TermParameter ob = new TermParameter(); DateTime FirstDateOfMonth = SystemInformation.CurrentSysInfo.NextPayProcessDate.FirstDateOfMonth(); DateTime LastDateOfMonth = SystemInformation.CurrentSysInfo.NextPayProcessDate.LastDateOfMonth(); //int TotalDaysInMonth = SystemInformation.CurrentSysInfo.NextPayProcessDate.TotalDaysInMonth(); List leaveEntries = LeaveEntry.Get(FirstDateOfMonth, LastDateOfMonth, EnumLeaveStatus.Approved); List leaves = Leave.Get(); if (leaveEntries == null || leaveEntries.Count == 0) { UpdateProgressStatus(EnumProcessStatus.End); return; } foreach (SalaryMonthly sMonthly in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); var empLeaveGroup = leaveEntries.Where(x => x.EmpID == sMonthly.EmployeeID.Integer) .GroupBy(x => x.LeaveID) .Select(x => new { LeaveID = x.Key, Days = x.Sum(y => y.ApprovedTotalDays) }).ToList(); foreach (var lEntry in empLeaveGroup) { Leave lv = leaves.FirstOrDefault(x => x.ID.Integer == lEntry.LeaveID.Integer); this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Leave_Days, lEntry.LeaveID.Integer, 0, lv != null ? lv.Code : "Unknown Leave", lEntry.Days); } } UpdateProgressStatus(EnumProcessStatus.End); } private void OverTimeArrearProcess() { OvertimeProcess process = null; ObjectsTemplate otProcesses = null; List empOTProcesses = null; Hashtable monthList = new Hashtable(); Hashtable employeeList = new Hashtable(); foreach (SalaryMonthly sMonthly in _salaryMonthlys) { foreach (EmployeeGradeSalary gradeSalary in sMonthly.ArrearGradeSalaries) { DateTime startdate = gradeSalary.EffectDate; while (startdate <= gradeSalary.TillDate) { if (monthList[GlobalFunctions.LastDateOfMonth(startdate)] == null) { monthList.Add(GlobalFunctions.LastDateOfMonth(startdate), GlobalFunctions.LastDateOfMonth(startdate)); } if (employeeList[gradeSalary.EmployeeID.Integer] == null) { employeeList.Add(gradeSalary.EmployeeID.Integer, gradeSalary.EmployeeID.Integer); } startdate = GlobalFunctions.LastDateOfMonth(GlobalFunctions.LastDateOfMonth(startdate).AddDays(1)); } } } otProcesses = OTProcess.GetbyOtMonth(employeeList, monthList); if (otProcesses != null && otProcesses.Count > 0) { process = new OvertimeProcess(); foreach (SalaryMonthly salaryMonthly in _salaryMonthlys) { foreach (EmployeeGradeSalary gradeSalary in salaryMonthly.ArrearGradeSalaries) { if (gradeSalary.GradeID.Integer == 2) continue; empOTProcesses = otProcesses.FindAll(delegate(OTProcess prs) { return prs.EmployeeID == gradeSalary.EmployeeID && prs.OTMonth >= gradeSalary.EffectDate; }); foreach (OTProcess empOTProcess in empOTProcesses) { if (empOTProcess.EmpOverTime == null) continue; OTProcess prs = process.ProcessArrear(empOTProcess, salaryMonthly.ThisMonthBasic); // SalaryMonthlyDetail basic = salaryMonthly.Details.Find(delegate(SalaryMonthlyDetail detail) { return (detail.ItemCode == EnumSalaryItemCode.Over_Time_Amount && detail.itemGroupCode == EnumSalaryGroup.Gross && detail.ItemID == empOTProcess.TermID.Integer); }); if (basic == null) this.AddDetail(salaryMonthly, EnumSalaryGroup.Gross, EnumSalaryItemCode.Over_Time_Amount, empOTProcess.TermID.Integer, empOTProcess.TermParameterID.Integer, empOTProcess.TermObj.Name, 0); SalaryMonthlyDetail arrearItem = salaryMonthly.Details.Find(delegate(SalaryMonthlyDetail detail) { return (detail.ItemCode == EnumSalaryItemCode.Over_Time_Amount && detail.itemGroupCode == EnumSalaryGroup.Arrear && detail.ItemID == empOTProcess.TermID.Integer); }); if (arrearItem == null) this.AddDetail(salaryMonthly, EnumSalaryGroup.Arrear, EnumSalaryItemCode.Over_Time_Amount, empOTProcess.TermID.Integer, empOTProcess.TermParameterID.Integer, empOTProcess.TermObj.Name + "-" + empOTProcess.MonthDate.ToString("MMM yyyy"), GlobalFunctions.Round(prs.Amount)); else { arrearItem.CalculatedAmount = arrearItem.CalculatedAmount + Math.Round(prs.Amount, 1); arrearItem.ChangedAmount = arrearItem.ChangedAmount + Math.Round(prs.Amount, 1); } } } } } } private void CalculateBonus() { UpdateProgressStatus(EnumProcessStatus.Start); DateTime dSalaryMonth = SystemInformation.CurrentSysInfo.NextPayProcessDate; ObjectsTemplate bonusdetails = BonusProcess.GetBonusDetails(dSalaryMonth, true); if (bonusdetails == null || bonusdetails.Count == 0) return; BonusProcess bp = BonusProcess.Get(bonusdetails[0].BonusID, dSalaryMonth); if (!bp.IsDisburseWithSalary) return; ObjectsTemplate bonuses = Bonus.Get(EnumStatus.Regardless); foreach (BonusProcess.BonusProcessDetail bonusdt in bonusdetails) { UpdateProgressStatus(EnumProcessStatus.PerformStep); SalaryMonthly sMonthly = _salaryMonthlys.Find(delegate(SalaryMonthly monthly) { return monthly.EmployeeID.Integer == bonusdt.EmployeeID.Integer; }); if (sMonthly != null) { Bonus ob = bonuses.GetItem(bonusdt.BonusID); this.AddDetail(sMonthly, EnumSalaryGroup.Gross, EnumSalaryItemCode.Bonus, bonusdt.BonusID.Integer, bonusdt.BonusProcessID.Integer, ob.Name, GlobalFunctions.Round(bonusdt.NetBonusAmount)); } } UpdateProgressStatus(EnumProcessStatus.End); } private void LoanProcess() { // UpdateProgressStatus(EnumProcessStatus.Start); // DateTime dSalaryMonth = SystemInformation.CurrentSysInfo.NextPayProcessDate; // ObjectsTemplate loanIssues = LoanIssue.Get(dSalaryMonth); // if (loanIssues == null || loanIssues.Count == 0) // { // UpdateProgressStatus(EnumProcessStatus.End); // return; // } // double loanAmounn = 0.0; // double actuInterest = 0.0; // double principleAmount = 0.0; // double interest = 0.0; // double balance = 0.0; // double sattelmentAmount = 0.0; // double nClosing = 0.0; //// bool withInerest = ConfigurationManager.GetBoolValue("loan", "combineinterestinsalary", EnumConfigurationType.Logic); // ObjectsTemplate oLoanScheduls = new ObjectsTemplate(); // oLoanScheduls = LoanSchedule.Get(); // foreach (LoanIssue issue in loanIssues) // { // UpdateProgressStatus(EnumProcessStatus.PerformStep); // SalaryMonthly sMonthly = _salaryMonthlys.Find(delegate(SalaryMonthly monthly) { return monthly.EmployeeID.Integer == issue.EmployeeID.Integer; }); // if (sMonthly != null) // { // sMonthly.CalculateTotal(); // ObjectsTemplate oschedules = issue.MonthlySchedules(dSalaryMonth); // if (oschedules == null) continue; // foreach (LoanSchedule schedule in oschedules) // { // nClosing = schedule.ClosingBalance; // //+ " principle" // this.AddDetail(sMonthly, EnumSalaryGroup.Deductions, EnumSalaryItemCode.Loan_Monthly_Installment, issue.LoanID.Integer, schedule.ID.Integer, issue.LoanObj.Name, GlobalFunctions.Round(schedule.InstallmentPrincipal)); // this.AddDetail(sMonthly, EnumSalaryGroup.Deductions, EnumSalaryItemCode.Loan_Monthly_Interest, issue.LoanID.Integer, schedule.ID.Integer, issue.LoanObj.Name + " interest", GlobalFunctions.Round(schedule.InstallmentInterest)); // //} // //else // // this.AddDetail(sMonthly, EnumSalaryGroup.Deductions, EnumSalaryItemCode.Loan_Monthly_Installment, issue.LoanID.Integer, schedule.ID.Integer, issue.LoanObj.Name + " principle", GlobalFunctions.Round(schedule.Installment)); // } // #region For Loan Remainig Amount // LoanIssue oLIssue = LoanIssue.GetExistingLoan(issue.LoanID, sMonthly.EmployeeID); // List oLSS = oLoanScheduls.FindAll(delegate(LoanSchedule oitem) { return oitem.LoanIssueID == oLIssue.ID; }); // if (oLSS.Count > 0) // { // loanAmounn = oLIssue.LoanAmount; // List oBeforeSMonths = oLSS.FindAll(delegate(LoanSchedule oitem) { return oitem.DueInstallmentDate <= GlobalFunctions.LastDateOfMonth(sMonthly.SalaryMonth); }); // actuInterest = 0.0; // principleAmount = 0.0; // interest = 0.0; // balance = 0.0; // sattelmentAmount = 0.0; // foreach (LoanSchedule oScedule in oBeforeSMonths) // { // actuInterest = actuInterest + oScedule.ActualInterest; // principleAmount = principleAmount + oScedule.InstallmentPrincipal; // interest = interest + oScedule.InstallmentInterest; // balance = balance + oScedule.OpeningBalance; // } // } // sattelmentAmount = (loanAmounn + actuInterest) - (principleAmount + interest); // this.AddDetail(sMonthly, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Loan_Remain_Balance, issue.LoanID.Integer, issue.ID.Integer, issue.LoanObj.Name + " balance", GlobalFunctions.Round(sattelmentAmount)); // #endregion // } // } // UpdateProgressStatus(EnumProcessStatus.End); DataSet oDataSet = LoanSchedule.Service.GetScheduleForSalary(_processMonth, SystemInformation.CurrentSysInfo.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(delegate(SalaryMonthly monthly) { return monthly.EmployeeID.Integer.ToString() == oRow["EMPLOYEEID"].ToString(); }); if (sMonthly != null) { sMonthly.CalculateTotal(); this.AddDetail(sMonthly, EnumSalaryGroup.Deductions, EnumSalaryItemCode.Loan_Monthly_Installment, Convert.ToInt32(oRow["LOANID"].ToString()), Convert.ToInt32(oRow["LOANSCHEDULEID"].ToString()), oRow["DESCRIPTION"].ToString(), 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(), GlobalFunctions.Round(Convert.ToDouble(oRow["InstallmentInterest"].ToString()))); } } UpdateProgressStatus(EnumProcessStatus.End); } private void Tax() { UpdateProgressStatus(EnumProcessStatus.Start); TaxCalculator taxCalculator = new TaxCalculator(); taxCalculator.AdParameters = _adParameters; bool bfixedAmount = ConfigurationManager.GetBoolValue("incometax", "fixedamount", EnumConfigurationType.Logic); bool isOtherItem = ConfigurationManager.GetBoolValue("incometax", "taxissalaryotheritem", EnumConfigurationType.Logic); EnumSalaryGroup ngroupCode = EnumSalaryGroup.Deductions; if (isOtherItem == true) ngroupCode = EnumSalaryGroup.OtherItem; taxCalculator.TaxParameter = TaxParameter.Get(SystemInformation.CurrentSysInfo.TaxParamID); ObjectsTemplate taxes = IncomeTax.Get(EnumIncomeTaxDataFrom.ProcessTempData); foreach (SalaryMonthly salary in _salaryMonthlys) { // if (salary.Employee.GradeID.Integer == 24 || salary.Employee.GradeID.Integer == 25) continue; salary.Incometaxes = new ObjectsTemplate(); UpdateProgressStatus(EnumProcessStatus.PerformStep); if (bfixedAmount == false) { taxCalculator.Salary = salary; taxCalculator.Employee = salary.Employee; taxCalculator.CurrentYearTax = IncomeTax.Get(taxes, 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 = IncomeTax.Get(salary.Incometaxes, salary.EmployeeID, EnumIncomeTaxItemGroup.Tax_Deducted, (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 { //SalaryMonthly oprvsalry = _PrvMonthsalary.Find(delegate(SalaryMonthly param) { return param.EmployeeID.Integer == salary.EmployeeID.Integer; }); //if (oprvsalry != null) //{ // SalaryMonthlyDetail odtl = oprvsalry.Details.Find(delegate(SalaryMonthlyDetail detail) { return (detail.ItemCode == EnumSalaryItemCode.Inc_Tax_Deduction && detail.itemGroupCode == EnumSalaryGroup.Deductions); }); // if (odtl != null) // { // if (Math.Abs(taxItem.ThisMonthAmount - odtl.ChangedAmount) <= 50) // taxItem.ThisMonthAmount = odtl.ChangedAmount; // } //} this.AddDetail(salary, ngroupCode, EnumSalaryItemCode.Inc_Tax_Deduction, (int)EnumSalaryItemCode.Inc_Tax_Deduction, 0, string.Empty, GlobalFunctions.Round(taxItem.ThisMonthAmount)); } } #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); TempUnAuthorized item = null; List items = new List(); ObjectsTemplate UnLeaves = UnAuthorizeLeaveParam.Get(); ObjectsTemplate empUnLeaves = EmployeeUnAuthorizeLeave.Get(EnumLeaveEntryType.Normal, _processMonth); DataSet dsAll = EmployeeUnAuthorizeLeave.GetAllUnAuthorizeLeave(_processMonth); // DataSet dsAll = EmployeeUnAuthorizeLeave.GetAllUnAuthorizeLeave(new DateTime(_nYear,1,5)); //DataSet dsThisMonth = EmployeeUnAuthorizeLeave.GetThisMonthUnAuthorizeLeave(_processMonth); int nTotalUnAuthorizedLeave = 0; int nThisMonthUnAuthorizedLeave = 0; int nTotalDays = 0; int nUnpaidDays = 0; //if (empUnLeaves == null || empUnLeaves.Count == 0) //{ // UpdateProgressStatus(EnumProcessStatus.End); // return; //} UnAuthorizeLeaveParamDetail unParamDetail = null; DataSet dsUnpaidLeaves = EmployeeUnAuthorizeLeave.GetUnPaidLeave(_nYear); foreach (DataRow dr in dsUnpaidLeaves.Tables[0].Rows) { TempUnAuthorized tu = new TempUnAuthorized(); tu.EmpID = Convert.ToInt16(dr[0].ToString()); tu.TotalUnAuthorizedDays = Convert.ToInt16(dr[1].ToString()); tu.BasicPaidDays = Convert.ToInt16(dr[2].ToString()); tu.OtherPaidDays = Convert.ToInt16(dr[3].ToString()); tu.BasicCurrentDeduct = Convert.ToInt16(dr[4].ToString()); tu.OtherCurrentDeduct = Convert.ToInt16(dr[5].ToString()); tu.BasicUnpaidDays = Convert.ToInt16(dr[6].ToString()); tu.OtherUnpaidDays = Convert.ToInt16(dr[7].ToString()); tu.LeaveID = Convert.ToInt16(dr[8].ToString()); tu.UnPaidLeaveYear = Convert.ToInt16(dr[9].ToString()); items.Add(tu); } foreach (SalaryMonthly salary in _salaryMonthlys) { nUnpaidDays = 0; nTotalDays = 0; nTotalUnAuthorizedLeave = 0; nThisMonthUnAuthorizedLeave = 0; TempUnAuthorized tEmp = items.Find(x => x.EmpID == salary.EmployeeID.Integer); if (tEmp == null) { item = new TempUnAuthorized(); item.EmpID = salary.EmployeeID.Integer; } else item = tEmp; salary.UnAuthorizedLeaves = new List(); UpdateProgressStatus(EnumProcessStatus.PerformStep); SalaryMonthlyDetail salaryDetail = null; double nAmount = 0; double nBasicThisMOnthDays = 0; if (dsAll.Tables[0] != null && dsAll.Tables[0].Rows.Count > 0) { DataRow dataRowAll = dsAll.Tables[0].AsEnumerable().Where(x => x.Field("EmployeeID") == salary.EmployeeID.Integer).SingleOrDefault(); if (dataRowAll != null) { nTotalUnAuthorizedLeave = Convert.ToInt16(dataRowAll[1].ToString()); } } UnAuthorizeLeaveParam Param = new UnAuthorizeLeaveParam(); if (nTotalUnAuthorizedLeave > 30) Param = UnLeaves[1]; else Param = UnLeaves[0]; if (Param == null) { ProcessStatus("Unauthorize leave parameter not found"); continue; } item.TotalUnAuthorizedDays = nTotalUnAuthorizedLeave; if (nTotalUnAuthorizedLeave > 30) { item.BasicCurrentDeduct = nTotalUnAuthorizedLeave - item.BasicPaidDays; item.BasicPaidDays += item.BasicCurrentDeduct; item.OtherCurrentDeduct = nTotalUnAuthorizedLeave - item.OtherPaidDays; //nTotalDays = nThisMonthUnAuthorizedLeave + nUnpaidDays; if (item.OtherCurrentDeduct > 16) { //nThisMonthUnAuthorizedLeave = (int)nTotalDays / 2; nUnpaidDays = (int)item.OtherCurrentDeduct / 2; item.OtherUnpaidDays = item.OtherCurrentDeduct - nUnpaidDays; item.OtherPaidDays += nUnpaidDays; item.OtherCurrentDeduct = nUnpaidDays; //nUnpaidDays = nTotalDays - nThisMonthUnAuthorizedLeave; //item.RemainingDays = item.TotalDays - nUnpaidDays; } else { item.OtherPaidDays += item.OtherCurrentDeduct; item.OtherUnpaidDays = 0; } } else { item.BasicCurrentDeduct = nTotalUnAuthorizedLeave - item.BasicPaidDays; item.BasicPaidDays += item.BasicCurrentDeduct; item.BasicUnpaidDays = 0; } foreach (UnAuthorizeLeaveParamDetail detail in Param.Details) { unParamDetail = detail; 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 = Ease.CoreV35.Utility.Global.DateFunctions.DateDiff("d", salary.Employee.JoiningDate, _processMonth) + 1; nAmount = nAmount / ndays; nAmount = nAmount * _processMonth.Day; } } else { nAmount = salary.GetAmountOnRange(salary.Employee, GlobalFunctions.FirstDateOfMonth(_processMonth), GlobalFunctions.LastDateOfMonth(_processMonth), EnumSalaryGroup.Gross, EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary); } //} //else //{ // nAmount = salary.GetAmountOnRange(salary.Employee, GlobalFunctions.FirstDateOfMonth(leave.LeaveMonth), // GlobalFunctions.LastDateOfMonth(leave.LeaveMonth), EnumSalaryGroup.Gross, // EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary); //} if (detail.Type == EnumSalaryComponent.Basic) { //nAmount = GlobalFunctions.ConevrtToDlyRateofMonth(nAmount, _processMonth) *( nBasicThisMOnthDays+item.RemainingDays); nAmount = GlobalFunctions.ConevrtToDlyRateofMonth(nAmount, _processMonth) * item.BasicCurrentDeduct; nAmount = nAmount * (detail.ValueInPercent / 100); //double nBasicPaid = new SalaryMonthly().GetUnAuthorizeAmountOnDateRange(salary.EmployeeID, GlobalFunctions.FirstDateOfYear(_processMonth), _processMonth, EnumSalaryGroup.UnauthLeave, EnumSalaryItemCode.Basic_Salary); //nAmount = nAmount - nBasicPaid; } else { // nAmount = GlobalFunctions.ConevrtToDlyRateofMonth(nAmount, _processMonth) * nThisMonthUnAuthorizedLeave; nAmount = GlobalFunctions.ConevrtToDlyRateofMonth(nAmount, _processMonth) * item.OtherCurrentDeduct; nAmount = nAmount * (detail.ValueInPercent / 100); } nAmount = GlobalFunctions.Round(nAmount); this.AddDetail(salary, EnumSalaryGroup.UnauthLeave, detail.Type == EnumSalaryComponent.Basic ? EnumSalaryItemCode.Basic_Salary : EnumSalaryItemCode.Allowance, detail.Type == EnumSalaryComponent.Basic ? (int)EnumSalaryItemCode.Basic_Salary : detail.AllowanceID.Integer, salaryDetail.SupportID.Integer, salaryDetail.Description, GlobalFunctions.Round(nAmount)); this.AddDetail(salary, EnumSalaryGroup.Miscellaneous, EnumSalaryItemCode.Tot_UnauthLeave_Days, Param.UnAhuthorizeLeaveID.Integer, 0, "UnAuthorized Leave Days", nThisMonthUnAuthorizedLeave); //if(nUnpaidDays>0) //{ // } } //} //item.currentDeduct = nUnpaidDays; //item.TotalDays = nTotalUnAuthorizedLeave; //if (nTotalUnAuthorizedLeave > 30) //{ // item.PaidDays += item.currentDeduct; // //item.RemainingDays = nUnpaidDays; //} //else //{ // item.PaidDays += item.currentDeduct; //} if (item.TotalUnAuthorizedDays > 0) salary.UnAuthorizedLeaves.Add(item); } 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.Integer); default: return false; } } private void PrepareCostcenterData() { UpdateProgressStatus(EnumProcessStatus.Start); ObjectsTemplate empCostCenters = EmployeeCostCenter.Get(); foreach (SalaryMonthly salary in _salaryMonthlys) { UpdateProgressStatus(EnumProcessStatus.PerformStep); ObjectsTemplate empinvolments = EmployeeCostCenter.Get(empCostCenters, salary.EmployeeID); if (empCostCenters == null) continue; salary.CostCentersInvolments = new ObjectsTemplate(); 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 class SalaryProcessStatus { public SalaryProcessStatus() { _employeeNo = ""; _name = ""; _remarks = ""; } #region EmployeeNo : Employee No private string _employeeNo; public string EmployeeNo { get { return _employeeNo; } set { _employeeNo = value; } } #endregion #region Employee Name : Employee Name private string _name; public string Name { get { return _name; } set { _name = value; } } #endregion #region remaks : remarks private string _remarks; public string Remarks { get { return _remarks; } set { _remarks = value; } } #endregion } }