2314 lines
131 KiB
C#
2314 lines
131 KiB
C#
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;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|