EchoTex_Payroll/HRM.DA/Service/Salary/SalaryCalculator.cs

2314 lines
131 KiB
C#
Raw Permalink Normal View History

2024-10-14 10:01:49 +06:00
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<Employee> _employees;
private List<AllowanceDeduction> _allowdeducitons;
private List<ProcessItem> _processItems;
private List<SalaryMonthly> _salaryMonthlys;
private List<SalaryProcessStatus> _processStatuses;
// private List<SalaryMonthly> _PrvMonthsalary;
private List<salaryHistory> _PrvMonthsalaryItems;
private List<salaryHistory> _salaryHistories;
private List<ADParameter> _adParameters;
public DateTime _processMonth;
public double _euroRate = 0;
private List<AttnMonthlyBenefit> _attnHours;
public event ProcessStatus ProcessStatus;
public event ProgressStatus ProgressStatus;
public List<Grade> _greades;
public List<AttnMonthlyBenefit> _attnBenifits;
// public List<EmployeeWorkPlanSetup> _empWorkPlans;
public List<DailyAttnProcess> _attnProcess;
List<BonusProcess.BonusProcessDetail> _bonusdetails;
private List<AttendanceForGrossFraction> _attendanceForGrossFraction;
private string _maternityCode;
public string _lwopCode;
private Dictionary<int, DateTime> _empIDsMLPartial = new Dictionary<int, DateTime>();
private Dictionary<int, double> _empIDsLWOP = new Dictionary<int, double>();
private List<int> _empIDsforMLRemoval = new List<int>();
bool isMaternityOutsidePayroll;
#endregion Define Class Veriable
public List<SalaryMonthly> SalaryMonthlies
{
get
{
return _salaryMonthlys;
}
}
public SalaryCalculator()
{
_processItems = new ProcessItemService().Get();
}
public List<SalaryProcessStatus> ErrorList
{
get
{
return _processStatuses;
}
}
public List<ADParameter> 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<Employee> Employees
{
get
{
return _employees;
}
}
public int PayrollTypeID { get; set; }
public void Process(List<Employee> 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<Employee> 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<SalaryProcessStatus>();
_salaryMonthlys = new List<SalaryMonthly>();
//_PrvMonthsalary = new SalaryMonthlyService().Get(
// GlobalFunctions.LastDateOfMonth(_processMonth.AddMonths(-1)), this.PayrollTypeID);
List<EnumSalaryItemCode> itemCodes = new List<EnumSalaryItemCode>();
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<EmployeeCostCenter> empCostCenters = new EmployeeCostCenterService().Get();
List<Category> categories = new CategoryService().Get(EnumStatus.Regardless, this.PayrollTypeID);
List<BATBGrandFatherTaging> gradFathers = new List<BATBGrandFatherTaging>(); //BATBGrandFatherTaging.Get();
_greades = new GradeService().Get(EnumStatus.Regardless, this.PayrollTypeID);
_attnBenifits = new List<AttnMonthlyBenefit>(); //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<EmployeeCostCenter> 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<EmployeeGradeSalary> 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<EmployeeGradeSalary> 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<PFException> 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<ADParameterEmployee> 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<ADParameterEmployee> indvAllowances, double toTalPresentDays)
{
double amount = 0;
EnumSalaryGroup groupCode = EnumSalaryGroup.Gross;
#region Individual Allowance
List<ADParameterEmployee> 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<EmployeeGradeSalary> gradeSalaries,
EnumSalaryGroup gCode, List<ADParameterEmployee> 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> otProcess = new OTProcessService().Get(this._processMonth);
if (otProcess == null || otProcess.Count == 0) return;
List<Term> trms = new TermService().Get(EnumStatus.Regardless, this.PayrollTypeID);
foreach (SalaryMonthly sMonthly in _salaryMonthlys)
{
UpdateProgressStatus(EnumProcessStatus.PerformStep);
List<OTProcess> 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<DailyAttnProcess> 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<Leave> 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<OTProcess> otProcesses = null;
List<OTProcess> empOTProcesses = null;
List<Term> oTerms = new TermService().Get(EnumStatus.Active, this.PayrollTypeID);
double arrAMount = 0;
List<TermParameter> 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<Bonus> 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<LoanIssue> 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<LoanSchedule> oLoanScheduls = new List<LoanSchedule>();
// //oLoanScheduls = LoanSchedule.Get();
// List<LoanSchedule> 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<LoanSchedule> 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<IncomeTax> taxes = new IncomeTaxService().Get(EnumIncomeTaxDataFrom.ProcessTempData, this.PayrollTypeID);
foreach (SalaryMonthly salary in _salaryMonthlys)
{
salary.Incometaxes = new List<IncomeTax>();
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<UnAuthorizeLeaveParam> UnLeaves = new UnAuthorizeLeaveParamService().Get(this.PayrollTypeID, true);
List<EmployeeUnAuthorizeLeave> 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<EmployeeUnAuthorizeLeave> 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<EmployeeCostCenter> empCostCenters = new EmployeeCostCenterService().Get();
foreach (SalaryMonthly salary in _salaryMonthlys)
{
UpdateProgressStatus(EnumProcessStatus.PerformStep);
List<EmployeeCostCenter> empinvolments = empCostCenters.FindAll(x=>x.EmployeeID == salary.EmployeeID);
if (empCostCenters == null) continue;
salary.CostCentersInvolments = new List<SalaryEmpCostCenter>();
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> _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<LeaveEntry> leaveEntries = new LeaveEntryService().Get(month.FirstDateOfMonth(), month.LastDateOfMonth(), EnumLeaveStatus.Approved);
List<Leave> 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<EmployeeGradeSalary> 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<int>("EMPID")).ToList();
}
if (ds.Tables.Count > 1 && ds.Tables[1].Rows.Count > 0)
{
_empIDsMLPartial = ds.Tables[1].AsEnumerable().Select(x => new { Key = x.Field<int>("EMPID"), Value = x.Field<DateTime>("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<int>();
_empIDsLWOP = new Dictionary<int, double>();
foreach (DataRow item in ds.Tables[2].Rows)
{
int days = item.Field<DateTime>("ToDate").Date.Subtract(item.Field<DateTime>("FromDate").Date).Days + 1;
if (_empIDsLWOP.ContainsKey(item.Field<int>("EMPID")))
{
_empIDsLWOP[item.Field<int>("EMPID")] = _empIDsLWOP[item.Field<int>("EMPID")] + days;
}
else
{
_empIDsLWOP.Add(item.Field<int>("EMPID"), days);
}
#region Commented Code for LWOP total salary removal
// if(_empIDsMLPartial.ContainsKey(item.Field<int>("EMPID")))
// {
// DateTime maternityEnd = _empIDsMLPartial[item.Field<int>("EMPID")];
// if(maternityEnd.AddDays(1).Date >= item.Field<DateTime>("FromDate").Date &&
// item.Field<DateTime>("ToDate").Date == endDate)
// {
// _empIDsforLWOPRemoval.Add(item.Field<int>("EMPID"));
// }
// else
// {
// _empIDsMLPartial[item.Field<int>("EMPID")] = maternityEnd.AddDays(item.Field<DateTime>("ToDate").Date.Subtract(item.Field<DateTime>("FromDate").Date).Days + 1);
// }
// }
// else
// {
// int days = item.Field<DateTime>("ToDate").Date.Subtract(item.Field<DateTime>("FromDate").Date).Days + 1;
// if((endDate.Subtract(startDate).Days +1) == days)
// {
// _empIDsforLWOPRemoval.Add(item.Field<int>("EMPID"));
// }
// else
// {
// if (_empIDsLWOP.ContainsKey(item.Field<int>("EMPID")))
// {
// if((endDate.Subtract(startDate).Days +1) == (_empIDsLWOP[item.Field<int>("EMPID")]+days))
// {
// _empIDsforLWOPRemoval.Add(item.Field<int>("EMPID"));
// }
// else
// {
// _empIDsLWOP[item.Field<int>("EMPID")] = _empIDsLWOP[item.Field<int>("EMPID")] + days;
// }
// }
// else
// {
// _empIDsLWOP.Add(item.Field<int>("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<AllowanceDeduction> oAllDeducts;
List<DailyAttnProcess> oAttnProcesses;
List<Shift> oShifts;
List<Leave> 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<SalaryMonthlyDetail> 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<SalaryMonthlyDetail> 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<SalaryMonthlyDetail> 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<SalaryMonthlyDetail> 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<DateTime> excludedLunchAllowDates = new List<DateTime>();
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<int> 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<string> 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<AttnNationalHoliday> 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<SalaryMonthlyDetail> smTempDetails = new List<SalaryMonthlyDetail>();
List<DailyAttnProcess> 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<SalaryMonthlyDetail> 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<SalaryMonthlyDetail> 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<int> 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<int> 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<SalaryMonthlyDetail> 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<ADParameterEmployee> 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<int> 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<int> 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<SalaryMonthlyDetail> 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<ADParameterEmployee> 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<SalaryMonthlyDetail> 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<int> oShiftIDs = tfshifts.Select(a => a.ID).ToList();
//List<int> 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<SalaryMonthlyDetail> 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<SalaryMonthlyDetail> 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;
}
}
}
}