using System; using System.Collections.Generic; using System.Linq; using System.Text; using Ease.CoreV35; using Ease.CoreV35.Model; using Ease.CoreV35.Caching; using System.Data.Linq.Mapping; using System.Data; namespace Payroll.BO { #region OPIProcessDetail [Serializable] public class OPIProcessDetail : BasicBaseObject { private ObjectsTemplate _employees; private ObjectsTemplate _processDetails; private ObjectsTemplate _opiParameters; private ObjectsTemplate _opiItems; private DataSet _dsOPIRegister; private ObjectsTemplate _processItems; private List _processStatuses; public DateTime _processMonth; public event ProcessStatus ProcessStatus; public event ProgressStatus ProgressStatus; #region Cache Store private static Cache _cache = new Cache(typeof(OPIProcessDetail)); #endregion #region Constructor public OPIProcessDetail() { _accountNo = string.Empty; _bankID = null; _branchID = null; _categoryID = null; _departmentID = null; _designationID = null; _employeeID = null; _gender = EnumGender.None; _gradeID = null; _isConfirmed = false; _isFinalize = false; _locationID = null; _oPIProcessID = null; _payrollTypeID = null; _pfMemberType = EnumPFMembershipType.Live; _religionID = null; _remarks = string.Empty; _oPIProcessDetailItems = null; _gradeSalaries = null; _employee = null; _arreargradeSalaries = null; _arrearPaidgradeSalaries = null; } #endregion #region Properties #region AccountNo : string private string _accountNo; public string AccountNo { get { return _accountNo; } set { base.OnPropertyChange("AccountNo", _accountNo, value); _accountNo = value; } } #endregion #region BankID : ID private ID _bankID; public ID BankID { get { return _bankID; } set { base.OnPropertyChange("BankID", _bankID, value); _bankID = value; } } #endregion #region BranchID : ID private ID _branchID; public ID BranchID { get { return _branchID; } set { base.OnPropertyChange("BranchID", _branchID, value); _branchID = value; } } #endregion #region CategoryID : ID private ID _categoryID; public ID CategoryID { get { return _categoryID; } set { base.OnPropertyChange("CategoryID", _categoryID, value); _categoryID = value; } } #endregion #region DepartmentID : ID private ID _departmentID; public ID DepartmentID { get { return _departmentID; } set { base.OnPropertyChange("DepartmentID", _departmentID, value); _departmentID = value; } } #endregion #region DesignationID : ID private ID _designationID; public ID DesignationID { get { return _designationID; } set { base.OnPropertyChange("DesignationID", _designationID, value); _designationID = value; } } #endregion #region EmployeeID : ID private ID _employeeID; public ID EmployeeID { get { return _employeeID; } set { base.OnPropertyChange("EmployeeID", _employeeID, value); _employeeID = value; } } #endregion #region Gender : EnumGender private EnumGender _gender; public EnumGender Gender { get { return _gender; } set { base.OnPropertyChange("Gender", (short)_gender, (short)value); _gender = value; } } #endregion #region GradeID : ID private ID _gradeID; public ID GradeID { get { return _gradeID; } set { base.OnPropertyChange("GradeID", _gradeID, value); _gradeID = value; } } #endregion #region IsConfirmed : bool private bool _isConfirmed; public bool IsConfirmed { get { return _isConfirmed; } set { base.OnPropertyChange("IsConfirmed", _isConfirmed, value); _isConfirmed = value; } } #endregion #region IsFinalize : bool private bool _isFinalize; public bool IsFinalize { get { return _isFinalize; } set { base.OnPropertyChange("IsFinalize", _isFinalize, value); _isFinalize = value; } } #endregion #region LocationID : ID private ID _locationID; public ID LocationID { get { return _locationID; } set { base.OnPropertyChange("LocationID", _locationID, value); _locationID = value; } } #endregion #region OPIProcessID : ID private ID _oPIProcessID; public ID OPIProcessID { get { return _oPIProcessID; } set { base.OnPropertyChange("OPIProcessID", _oPIProcessID, value); _oPIProcessID = value; } } #endregion #region PayrollTypeID : ID private ID _payrollTypeID; public ID PayrollTypeID { get { return _payrollTypeID; } set { base.OnPropertyChange("PayrollTypeID", _payrollTypeID, value); _payrollTypeID = value; } } #endregion #region PFMemberType : EnumPFMembershipType private EnumPFMembershipType _pfMemberType; public EnumPFMembershipType PFMemberType { get { return _pfMemberType; } set { base.OnPropertyChange("PFMemberType", (short)_pfMemberType, (short)value); _pfMemberType = value; } } #endregion #region ReligionID : ID private ID _religionID; public ID ReligionID { get { return _religionID; } set { base.OnPropertyChange("ReligionID", _religionID, value); _religionID = value; } } #endregion #region Remarks : string private string _remarks; public string Remarks { get { return _remarks; } set { base.OnPropertyChange("Remarks", _remarks, value); _remarks = value; } } #endregion #region OPIProcessDetailItem private ObjectsTemplate _oPIProcessDetailItems; public ObjectsTemplate OPIProcessDetailItems { get { //Do not change this property if (_oPIProcessDetailItems == null ) { _oPIProcessDetailItems = new ObjectsTemplate(); } return this._oPIProcessDetailItems; } set { _oPIProcessDetailItems = value; } } #endregion #region Employee : Employee private Employee _employee; public Employee Employee { get { if (_employeeID.Integer > 0 && _employee == null) { _employee = new Employee(); _employee = Payroll.BO.Employee.Get(_employeeID); } return this._employee; } set { _employee = value; } } #endregion #region Grade Salaries : ObjectsTemplate private ObjectsTemplate _gradeSalaries; public ObjectsTemplate GradeSalaries { get { if (_gradeSalaries == null) { throw new ServiceException("Grade Salary not yet set"); } return _gradeSalaries; } set { _gradeSalaries = value; } } #endregion #region Arrear Grade Salaries : ObjectsTemplate private ObjectsTemplate _arreargradeSalaries; public ObjectsTemplate ArrearGradeSalaries { get { if (_arreargradeSalaries == null) { // throw new ServiceException("Arrear Grade Salary not yet set"); _arreargradeSalaries = new ObjectsTemplate(); } return _arreargradeSalaries; } set { _arreargradeSalaries = value; } } #endregion #region Arrear Paid Grade Salaries : ObjectsTemplate private ObjectsTemplate _arrearPaidgradeSalaries; public ObjectsTemplate ArrearPaidGradeSalaries { get { if (_arrearPaidgradeSalaries == null) { _arrearPaidgradeSalaries = new ObjectsTemplate(); } return _arrearPaidgradeSalaries; } set { _arrearPaidgradeSalaries = value; } } #endregion #region Service Factory IOPIProcessDetailService : IOPIProcessDetailService internal static IOPIProcessDetailService Service { get { return Services.Factory.CreateService(typeof(IOPIProcessDetailService)); } } #endregion public List Errors { get { return _processStatuses; } } #endregion #region Functions public static OPIProcessDetail Get(ID nOPIProcessDetailID) { OPIProcessDetail oOPIProcessDetail = null; #region Cache Header oOPIProcessDetail = (OPIProcessDetail)_cache["Get", nOPIProcessDetailID]; if (oOPIProcessDetail != null) return oOPIProcessDetail; #endregion oOPIProcessDetail = OPIProcessDetail.Service.Get(nOPIProcessDetailID); #region Cache Footer _cache.Add(oOPIProcessDetail, "Get", nOPIProcessDetailID); #endregion return oOPIProcessDetail; } public static ObjectsTemplate Get() { #region Cache Header ObjectsTemplate oOPIProcessDetails = _cache["Get"] as ObjectsTemplate; if (oOPIProcessDetails != null) return oOPIProcessDetails; #endregion try { oOPIProcessDetails = Service.Get(); } catch (ServiceException e) { throw new Exception(e.Message, e); } #region Cache Footer _cache.Add(oOPIProcessDetails, "Get"); #endregion return oOPIProcessDetails; } public ID Save() { this.SetAuditTrailProperties(); return OPIProcessDetail.Service.Save(this); } public void Delete(ID id) { OPIProcessDetail.Service.Delete(id); } #region ProgressBar private void UpdateprocessStatus(string statusString) { if (ProcessStatus != null) ProcessStatus(statusString); } private void UpdateProgressStatus(EnumProcessStatus status) { if (ProgressStatus != null) ProgressStatus(status); } #endregion public ObjectsTemplate Process(ObjectsTemplate employees, DateTime processMonth) { //SalaryException oSException = new SalaryException(); _employees = employees; _processMonth = processMonth; UpdateprocessStatus("Collecting Employee basic information...."); //this.Initialize(); this.AddEmployeeToProcessDetail(); //if (_processStatuses.Count > 0) return; UpdateprocessStatus("Calculating Employee basic Salary...."); this.BasicSalary(); UpdateprocessStatus("Calculating Employees benifits and deduction...."); this.OPIItems(); //this.LeavePrepare(oSException.GetEmpLeaveStatus()); return _processDetails; } private void AddEmployeeToProcessDetail() { _processDetails = new ObjectsTemplate(); UpdateProgressStatus(EnumProcessStatus.Start); foreach (Employee employee in _employees) { UpdateProgressStatus(EnumProcessStatus.PerformStep); GlobalFunctions.UpdateStatus(" Collecting information for the employee " + employee.Name + " ( " + employee.EmployeeNo + ")"); OPIProcessDetail procDetail = new OPIProcessDetail(); procDetail.CategoryID = employee.CategoryID; procDetail.EmployeeID = employee.ID; procDetail.Gender = employee.Gender; procDetail.IsConfirmed = employee.IsConfirmed; procDetail.PayrollTypeID = employee.PayrollTypeID; procDetail.PFMemberType = employee.PFMemberType; procDetail.ReligionID = employee.ReligionID; procDetail.GradeID = employee.GradeID; procDetail.DepartmentID = employee.DepartmentID; procDetail.DesignationID = employee.DesignationID; procDetail.LocationID = employee.LocationID; if (employee.PaymentMode == EnumPaymentMode.BankTransfer) { procDetail.BranchID = employee.BranchID; Branch branch = new Branch(); branch = Branch.Get(employee.BranchID); procDetail.BankID = branch.BankID; procDetail.AccountNo = employee.AccountNo; } else { procDetail.BranchID = ID.FromInteger(0); procDetail.BankID = ID.FromInteger(0); } procDetail.Employee = employee; _processDetails.Add(procDetail); } 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 BasicSalary() { //GetCurrentMonthSalaryItems function return current month's employee grade, salary and effect date. //effect date must sorted, otherwise error will be generated from next function. #region Calculate Normal Salary ObjectsTemplate gradeSalaryItems = EmployeeGradeSalary.Service.GetCurrMonthSalaryItems(SystemInformation.CurrentSysInfo.NextPayProcessDate); foreach (OPIProcessDetail opiProcess in _processDetails ) { opiProcess.GradeSalaries = EmployeeGradeSalary.Get(gradeSalaryItems, opiProcess.EmployeeID); if (opiProcess.GradeSalaries.Count == 0) continue; EmployeeGradeSalary.PrepareDataForCurrentSalary(opiProcess.Employee, opiProcess.GradeSalaries); } #endregion Calculate Normal Salary #region calculate arrear amount ObjectsTemplate arrearItems = EmployeeGradeSalary.Service.GetArrearItems(); foreach (OPIProcessDetail opiProcess in _processDetails) { opiProcess.ArrearGradeSalaries = EmployeeGradeSalary.Get(arrearItems, opiProcess.EmployeeID); if (opiProcess.ArrearGradeSalaries.Count > 0) { DateTime arrearPaidFrom = opiProcess.ArrearGradeSalaries[0].EffectDate; opiProcess.ArrearPaidGradeSalaries = EmployeeGradeSalary.Service.GetArrearPaidItems(opiProcess.EmployeeID, arrearPaidFrom); } } #endregion calculate arrear amount } private void OPIItems() { _opiParameters = OpiParameter.Get(EnumStatus.Active); if (_opiParameters == null || _opiParameters.Count == 0) return; ObjectsTemplate opiIndividuals = OpiParameterIndividual.Service.Get( GlobalFunctions.FirstDateOfMonth(_processMonth), GlobalFunctions.LastDateOfMonth(_processMonth)); OpiParameter paramter = new OpiParameter(); ObjectsTemplate paramters; foreach (OPIProcessDetail detail in _processDetails) { // Regular Grade defined parameters paramters = paramter.ApplicableParameters(detail.Employee, detail, _opiParameters, detail.GradeSalaries); this.GradeDefinedOpiItem(detail, detail.GradeSalaries, paramters); // Arrear Grade defined parameters paramters = paramter.ApplicableParameters(detail.Employee, detail, _opiParameters, detail.ArrearGradeSalaries); this.GradeDefinedOpiItem(detail, detail.GradeSalaries, paramters); // Arrear already paid parameters paramters = paramter.ApplicableParameters(detail.Employee, detail, _opiParameters, detail.ArrearPaidGradeSalaries); this.GradeDefinedOpiItem(detail, detail.GradeSalaries, paramters); //this.IndividualOpiItem(detail, opiIndividuals); } } private void Add(OPIProcessDetail processDetail, OPIProcessDetailItem item) { OPIProcessDetailItem existItem = processDetail.OPIProcessDetailItems.Find(delegate(OPIProcessDetailItem fItem) { return fItem.OPIItemID == item.OPIItemID; }); if (existItem == null) { processDetail.OPIProcessDetailItems.Add(item); } else { existItem.NetAmount = existItem.NetAmount + item.NetAmount; existItem.ChangeNetAmount = existItem.ChangeNetAmount + item.ChangeNetAmount; existItem.Description = item.Description; } } private void GradeDefinedOpiItem(OPIProcessDetail detail, ObjectsTemplate gradeSalaries, ObjectsTemplate paramters) { double amount = 0, totalAmount = 0, paidAmount = 0, remainingAmount, indvAmnt = 0, fractionAmount = 0; int totalMonth = 12, paidMonth = 0, remainingMonth = 0; //int randomEmployee = (new Random()).Next(1, _employees.Count); int empNumber = 1; foreach (EmployeeGradeSalary empGradeSalary in gradeSalaries) { foreach (OpiParameter parameter in paramters) { if (parameter.EntitleType == EnumEntitleType.Grade) { //amount = parameter.GetGradeDefinedAmount(detail.Employee, empGradeSalary.BasicSalary, empGradeSalary.GrossSalary); if (parameter.IsFlatAmount == true) amount = amount * empGradeSalary.FractionofFromTo; } else continue; OPIProcessDetailItem opdItem = new OPIProcessDetailItem(); switch (parameter.OpiPeriodicity) { case EnumOpiPeriodicity.Monthly: opdItem.NetAmount = amount; opdItem.ChangeNetAmount = amount; //opdItem.TaxAmount = break; case EnumOpiPeriodicity.OnceOff: opdItem.NetAmount = amount; opdItem.ChangeNetAmount = amount; //opdItem.TaxAmount = break; case EnumOpiPeriodicity.Annual: paidMonth = Convert.ToInt32(Payroll.BO.SystemInformation.CurrentSysInfo.NextPayProcessDate.Date.Month); remainingMonth = totalMonth - (paidMonth); totalAmount = amount * totalMonth; paidAmount = paidMonth * amount; remainingAmount = totalAmount - paidAmount; opdItem.NetAmount = remainingAmount / remainingMonth; opdItem.ChangeNetAmount = remainingAmount / remainingMonth; //opdItem.TaxAmount = break; //case EnumOpiPeriodicity.AveragePayment: // break; //case EnumOpiPeriodicity.OnAmount: // indvAmnt = amount / _processDetails.Count; // fractionAmount = (indvAmnt - Math.Round(indvAmnt, 0)) * _processDetails.Count; // if (empNumber == gradeSalaries.Count) // { // opdItem.NetAmount = Math.Round(indvAmnt, 0) + fractionAmount; // opdItem.ChangeNetAmount = Math.Round(indvAmnt, 0) + fractionAmount; // } // else // { // opdItem.NetAmount = Math.Round(indvAmnt, 0); // opdItem.ChangeNetAmount = Math.Round(indvAmnt, 0); // } // //opdItem.TaxAmount = // break; default: break; } opdItem.Description = parameter.OpiItem.Name; opdItem.OPIItemID = parameter.OpiItemID; opdItem.OPIProcessDetailID = this.ID; opdItem.OPIType = parameter.OpiItem.OpiType; _opiItems = OpiItem.Get(); if (_opiItems != null && _opiItems.Count > 0) opdItem.Sequence = _opiItems.GetItem(parameter.OpiItem.ID).Sequence; this.Add(detail, opdItem); // add the item in the collection } empNumber++; } } private void IndividualOpiItem(OPIProcessDetail detail, ObjectsTemplate opiIndividuals) { //double amount = 0; //EnumSalaryGroup groupCode = EnumSalaryGroup.Gross; //#region Individual Allowance //List items = opiIndividuals.FindAll(delegate(OpiParameterIndividual item) //{ // return item.EmployeeId.Integer == detail.Employee.ID.Integer && item.IndividualType == EnumOPIIndivdualType.AppliedToIndividual; //}); //foreach (OpiParameterIndividual item in items) //{ // amount = 0; // OpiParameter parameter = _opiParameters.GetItem(item.OpiParameterID); // amount = parameter.GetIndividualAmount(detail.Employee, _processMonth, item, // detail.Employee.GrossSalary, detail.GetGrossAmount(EnumSalaryItemCode.Basic_Salary, (int)EnumSalaryItemCode.Basic_Salary)); // EnumSalaryItemCode itemCode = EnumSalaryItemCode.Allowance; // groupCode = EnumSalaryGroup.Gross; // if (parameter.AllowOrDeductType == EnumAllowOrDeduct.Deduction) // { // itemCode = EnumSalaryItemCode.Deduction; // groupCode = EnumSalaryGroup.Deductions; // } // if (item.Arreartype == EnumArrearType.ToCalculate) groupCode = EnumSalaryGroup.Arrear; // SalaryMonthlyDetail detail = salary.GetDetail(groupCode, itemCode, parameter.AllowDeductID.Integer); // if (detail == null) // detail = this.AddDetail(salary, groupCode, itemCode, parameter.AllowDeductID.Integer, parameter.ID.Integer, parameter.AllowanceDeduction.Name, amount); // else // { // detail.CalculatedAmount = detail.CalculatedAmount + amount; // detail.CalculatedAmount = GlobalFunctions.Round(detail.CalculatedAmount); // detail.ChangedAmount = detail.CalculatedAmount; // } // detail.Position = item.AllowDeduct.Sequence + 1; //} //#endregion Individual Allowance } #endregion public static ObjectsTemplate GetDetail(DateTime _SalaryMonth) { #region Cache Header ObjectsTemplate oOPIProcessDetails = _cache["Get"] as ObjectsTemplate; if (oOPIProcessDetails != null) return oOPIProcessDetails; #endregion try { oOPIProcessDetails = Service.Get(_SalaryMonth); } catch (ServiceException e) { throw new Exception(e.Message, e); } #region Cache Footer _cache.Add(oOPIProcessDetails, "Get"); #endregion return oOPIProcessDetails; } } #endregion #region IOPIProcessDetail Service public interface IOPIProcessDetailService { OPIProcessDetail Get(ID id); ObjectsTemplate Get(); ID Save(OPIProcessDetail item); void Save(OPIProcess oProcess, ObjectsTemplate oPDetails); void Delete(ID id); ObjectsTemplate Get(DateTime _SalaryMonth); } #endregion }