using System;
using System.Data;
using System.Linq;
using Ease.Core.Model;
using Ease.Core.DataAccess;
using Ease.Core.Utility;
using Payroll.Service;
using System.Collections.Generic;
using HRM.BO;

namespace HRM.DA
{
    public class EmployeeGradeSalaryService : ServiceTemplate, IEmployeeGradeSalaryService
    {
        public EmployeeGradeSalaryService()
        {
        }

        private void MapObject(EmployeeGradeSalary oEmployeeGradeSalary, DataReader oReader)
        {
            base.SetObjectID(oEmployeeGradeSalary, oReader.GetInt32("EmpGradeSalaryID").Value);
            oEmployeeGradeSalary.EmployeeSerial = oReader.GetInt32("GradeSalaryID").Value;
            oEmployeeGradeSalary.EmployeeID = oReader.GetInt32("EmployeeID").Value;
            oEmployeeGradeSalary.TillDate = oReader.GetDateTime("tillDate");
            oEmployeeGradeSalary.EffectDate = oReader.GetDateTime("effectDate").Value;
            oEmployeeGradeSalary.GradeID = oReader.GetInt32("gradeID", 0);
            oEmployeeGradeSalary.BasicSalary = oReader.GetDouble("basicSalary").Value;
            oEmployeeGradeSalary.GrossSalary = oReader.GetDouble("grossSalary").Value;
            oEmployeeGradeSalary.PayScaleDetailID = oReader.GetInt32("payScaleID", 0);
            oEmployeeGradeSalary.ArrearType = (EnumArrearType)oReader.GetInt32("arrearInfo").Value;
            oEmployeeGradeSalary.Increment = oReader.GetDouble("incrementNo") ;
            oEmployeeGradeSalary.GradeSalaryTypeID = oReader.GetInt32("gradeSalaryTypeID", 0);
            oEmployeeGradeSalary.CreatedBy = oReader.GetInt32("CreatedBy", 0);
            oEmployeeGradeSalary.CreatedDate = oReader.GetDateTime("CreatedDate").Value;
            oEmployeeGradeSalary.ModifiedBy = oReader.GetInt32("ModifiedBy", 0);
            oEmployeeGradeSalary.ModifiedDate = oReader.GetDateTime("ModifiedDate");
            this.SetObjectState(oEmployeeGradeSalary, Ease.Core.ObjectState.Saved);
        }

        protected override T CreateObject<T>(DataReader oReader)
        {
            EmployeeGradeSalary oEmployeeGradeSalary = new EmployeeGradeSalary();
            MapObject(oEmployeeGradeSalary, oReader);
            return oEmployeeGradeSalary as T;
        }

        #region Service implementation

        public EmployeeGradeSalary GetRelatedData(EmployeeGradeSalary oEmployeeGradeSalary, TransactionContext tc)
        {
            oEmployeeGradeSalary.Grade = (new GradeService()).Get(tc, oEmployeeGradeSalary.GradeID);
            oEmployeeGradeSalary.Employee = (new EmployeeService()).Get(tc, oEmployeeGradeSalary.EmployeeID);
            oEmployeeGradeSalary.gradeSalaryType = (new GradeSalaryChangeTypeService()).Get(tc, oEmployeeGradeSalary.GradeSalaryTypeID);
        //    oEmployeeGradeSalary.PayScaleDetail = (new PayScaleDetailService()).Get(tc, oEmployeeGradeSalary.PayScaleDetailID);
            return oEmployeeGradeSalary;
        }

        public EmployeeGradeSalary Get(int employeeid, DateTime effectDate, EnumArrearType type)
        {
            EmployeeGradeSalary oEmployeeGradeSalary = null;

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader oreader = new DataReader(EmployeeGradeSalaryDA.Get(tc, employeeid, effectDate, type));
                if (oreader.Read())
                {
                    oEmployeeGradeSalary = this.CreateObject<EmployeeGradeSalary>(oreader);
                    //GetRelatedData(oEmployeeGradeSalary, tc);
                }

                oreader.Close();
                GetRelatedData(oEmployeeGradeSalary, tc);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmployeeGradeSalary;
        }

        public List<EmployeeGradeSalary> GetBasicOnDate(DateTime effectDate)
        {
            List<EmployeeGradeSalary> oEmployeeGradeSalarys = null;

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader oreader =
                    new DataReader(EmployeeGradeSalaryDA.GetBasicOnDate(tc, effectDate));
                if (oreader.Read())
                {
                    oEmployeeGradeSalarys = this.CreateObjects<EmployeeGradeSalary>(oreader);
                }

                oreader.Close();
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmployeeGradeSalarys;
        }
        public EmployeeGradeSalary GetBasicOnDateBAT(int employeeid, DateTime effectDate)
        {
            EmployeeGradeSalary oEmployeeGradeSalary = null;

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader oreader =
                    new DataReader(EmployeeGradeSalaryDA.GetBasicOnDateBAT(tc, employeeid, effectDate));
                if (oreader.Read())
                {
                    oEmployeeGradeSalary = this.CreateObject<EmployeeGradeSalary>(oreader);
                //    GetRelatedData(oEmployeeGradeSalary, tc);
                }

                oreader.Close();
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmployeeGradeSalary;
        }

        public List<EmployeeGradeSalary> Get(DateTime effectDate, EnumArrearType type)
        {
            List<EmployeeGradeSalary> employeeGradeSalarys = new List<EmployeeGradeSalary>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dr = new DataReader(EmployeeGradeSalaryDA.Get(tc, effectDate, type));
                employeeGradeSalarys = this.CreateObjects<EmployeeGradeSalary>(dr);
                
                dr.Close();

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return employeeGradeSalarys;
        }

        public EmployeeGradeSalary Get(int employeeid, DateTime effectDate, int payrollTypeID)
        {
            EmployeeGradeSalary oEmployeeGradeSalary = null;

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader oreader =
                    new DataReader(EmployeeGradeSalaryDA.Get(tc, employeeid, effectDate, payrollTypeID));
                if (oreader.Read())
                {
                    oEmployeeGradeSalary = this.CreateObject<EmployeeGradeSalary>(oreader);
                }
                oreader.Close();
                if (oEmployeeGradeSalary != null)
                {
                    GetRelatedData(oEmployeeGradeSalary, tc);
                }
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmployeeGradeSalary;
        }

        public EmployeeGradeSalary Get(TransactionContext tc, int employeeid, DateTime effectDate, EnumArrearType type)
        {
            EmployeeGradeSalary oEmployeeGradeSalary = null;

            try
            {
                DataReader oreader = new DataReader(EmployeeGradeSalaryDA.Get(tc, employeeid, effectDate, type));
                if (oreader.Read())
                {
                    oEmployeeGradeSalary = this.CreateObject<EmployeeGradeSalary>(oreader);
                   // GetRelatedData(oEmployeeGradeSalary, tc);
                }

                oreader.Close();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmployeeGradeSalary;
        }

        public EmployeeGradeSalary GetMax(int employeeID, EnumArrearType type)
        {
            EmployeeGradeSalary oEmployeeGradeSalary = null;

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader oreader = new DataReader(EmployeeGradeSalaryDA.GetMax(tc, employeeID, type));
                if (oreader.Read())
                {
                    oEmployeeGradeSalary = this.CreateObject<EmployeeGradeSalary>(oreader);
                    GetRelatedData(oEmployeeGradeSalary, tc);
                }

                oreader.Close();
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmployeeGradeSalary;
        }

        public EmployeeGradeSalary GetMax(TransactionContext tc, int employeeID, EnumArrearType type)
        {
            EmployeeGradeSalary oEmployeeGradeSalary = null;
            try
            {
                DataReader oreader = new DataReader(EmployeeGradeSalaryDA.GetMax(tc, employeeID, type));
                if (oreader.Read())
                {
                    oEmployeeGradeSalary = this.CreateObject<EmployeeGradeSalary>(oreader);
                }
                oreader.Close();

//                GetRelatedData(oEmployeeGradeSalary, tc);

               
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmployeeGradeSalary;
        }


        public EmployeeGradeSalary GetbyID(TransactionContext tc, int EmpGradeSalaryID)
        {
            EmployeeGradeSalary oEmployeeGradeSalary = null;

            try
            {
                DataReader oreader = new DataReader(EmployeeGradeSalaryDA.GetbyID(tc, EmpGradeSalaryID));
                if (oreader.Read())
                {
                    oEmployeeGradeSalary = this.CreateObject<EmployeeGradeSalary>(oreader);
                  //  GetRelatedData(oEmployeeGradeSalary, tc);
                }

                oreader.Close();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmployeeGradeSalary;
        }

        public EmployeeGradeSalary GetPeviousSalary(int employeeid, int gradeSalaryID)
        {
            EmployeeGradeSalary oEmployeeGradeSalary = null;
            DataSet oEmpBasicGrades = new DataSet();
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader oreader =
                    new DataReader(EmployeeGradeSalaryDA.GetPeviousSalary(tc, employeeid, gradeSalaryID));
                if (oreader.Read())
                {
                    oEmployeeGradeSalary = this.CreateObject<EmployeeGradeSalary>(oreader);
                    GetRelatedData(oEmployeeGradeSalary, tc);
                }

                oreader.Close();
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmployeeGradeSalary;
        }
        public DataSet GetEmpPromotion(DateTime dEffectDate, DateTime dEffectDate2, int payrollTypeID)
        {
            DataSet oEmpBasicGrades = new DataSet();
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                oEmpBasicGrades = EmployeeGradeSalaryDA.GetEmpPromotion(tc, dEffectDate, dEffectDate2, payrollTypeID);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmpBasicGrades;
        }

        
        public DataSet GetEmpBasicGrade(DateTime dEffectDate, DateTime dEffectDate2, int payrollTypeID)
        {
            DataSet oEmpBasicGrades = new DataSet();
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                oEmpBasicGrades = EmployeeGradeSalaryDA.GetEmpBasicGrade(tc, dEffectDate, dEffectDate2, payrollTypeID);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmpBasicGrades;
        }

        public DataSet GetEmpPrvBasicGrade(DateTime dEffectDate, int payrollTypeID)
        {
            DataSet oEmpBasicGrades = new DataSet();
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                oEmpBasicGrades = EmployeeGradeSalaryDA.GetEmpPrvBasicGrade(tc, dEffectDate, payrollTypeID);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmpBasicGrades;
        }

        public DataSet GetmultipleTilldatedemp(int payrollTypeID)
        {
            DataSet oEmpBasicGrades = new DataSet();
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                oEmpBasicGrades = EmployeeGradeSalaryDA.GetmultipleTilldatedemp(tc, payrollTypeID);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmpBasicGrades;
        }



        public List<EmployeeGradeSalary> Get(int employeeID)
        {
            List<EmployeeGradeSalary> employeeGradeSalarys = new List<EmployeeGradeSalary>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dr = new DataReader(EmployeeGradeSalaryDA.Get(tc, employeeID));
                employeeGradeSalarys = this.CreateObjects<EmployeeGradeSalary>(dr);
                dr.Close();

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return employeeGradeSalarys;
        }
        public DataTable GetSalaryHistory(int employeeID)
        {
            DataTable employeeGradeSalarys = null;

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                employeeGradeSalarys= EmployeeGradeSalaryDA.GetSalaryHistory(tc, employeeID);

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return employeeGradeSalarys;
        }
        
        public List<EmployeeGradeSalary> Get()
        {
            List<EmployeeGradeSalary> employeeGradeSalarys = new List<EmployeeGradeSalary>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dr = new DataReader(EmployeeGradeSalaryDA.Get(tc));
                employeeGradeSalarys = this.CreateObjects<EmployeeGradeSalary>(dr);
                dr.Close();

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return employeeGradeSalarys;
        }

        public List<EmployeeGradeSalary> GetCurrMonthSalaryItems(DateTime nextPayProcessDate, int payrolltypeid)
        {
            List<EmployeeGradeSalary> employeeGradeSalarys = new List<EmployeeGradeSalary>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dr =
                    new DataReader(
                        EmployeeGradeSalaryDA.GetCurrMonthSalaryItems(tc, nextPayProcessDate, payrolltypeid));
                employeeGradeSalarys = this.CreateObjects<EmployeeGradeSalary>(dr);
                dr.Close();

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return employeeGradeSalarys;
        }

        public List<EmployeeGradeSalary> GetArrearPaidItems(int emlpoyeeid, DateTime tillDateFrom, int payrollTypeID)
        {
            List<EmployeeGradeSalary> employeeGradeSalarys = new List<EmployeeGradeSalary>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dr =
                    new DataReader(
                        EmployeeGradeSalaryDA.GetArrearPaidItems(tc, emlpoyeeid, tillDateFrom, payrollTypeID));
                employeeGradeSalarys = this.CreateObjects<EmployeeGradeSalary>(dr);
                dr.Close();

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return employeeGradeSalarys;
        }

        public List<EmployeeGradeSalary> GetArrearItems(int payrollTypeID)
        {
            List<EmployeeGradeSalary> employeeGradeSalarys = new List<EmployeeGradeSalary>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dr = new DataReader(EmployeeGradeSalaryDA.GetArrearItems(tc, payrollTypeID));
                employeeGradeSalarys = this.CreateObjects<EmployeeGradeSalary>(dr);
                dr.Close();

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return employeeGradeSalarys;
        }


        public List<EmployeeGradeSalary> GetbyTillDate(TransactionContext tc, int employeeId,
            DateTime tillDateFrom, DateTime tillDateTo)
        {
            List<EmployeeGradeSalary> employeeGradeSalarys = new List<EmployeeGradeSalary>();

            //TransactionContext tc = null;
            try
            {
                //tc = TransactionContext.Begin();

                DataReader dr =
                    new DataReader(EmployeeGradeSalaryDA.GetbyTillDate(tc, employeeId, tillDateFrom, tillDateTo));
                employeeGradeSalarys = this.CreateObjects<EmployeeGradeSalary>(dr);
                dr.Close();

                //tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return employeeGradeSalarys;
        }

        public List<EmployeeGradeSalary> GetbyEffectDate(int employeeId,
            DateTime effectDateFrom, DateTime effectDateTo)
        {
            List<EmployeeGradeSalary> employeeGradeSalarys = new List<EmployeeGradeSalary>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dr =
                    new DataReader(EmployeeGradeSalaryDA.GetbyEffectDate(tc, employeeId, effectDateFrom, effectDateTo));
                employeeGradeSalarys = this.CreateObjects<EmployeeGradeSalary>(dr);
                dr.Close();

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return employeeGradeSalarys;
        }

        public void Save(List<EmployeeGradeSalary> itemsToSave)
        {
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin(true);
                this.Save(tc, itemsToSave);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        public void Save(TransactionContext tc, List<EmployeeGradeSalary> itemsToSave)
        {
            try
            {
                foreach (EmployeeGradeSalary item in itemsToSave)
                {
                    if (item.IsNew)
                    {
                        int id = tc.GenerateID("GRADESALARYASSIGNMENT", "EmpGradeSalaryID");
                        base.SetObjectID(item, id);
                        id = tc.GenerateID("GRADESALARYASSIGNMENT", "GradeSalaryID",
                            SQLParser.MakeSQL("WHERE EmployeeID=%n", item.EmployeeID));
                        item.EmployeeSerial = id;
                        EmployeeGradeSalaryDA.Insert(tc, item);
                    }
                    else
                    {
                        EmployeeGradeSalaryDA.Update(tc, item);
                    }
                    //EmployeeDA.UpdateOTFlag(tc, item.EmployeeID);
                }


                bool bvalid =
                   new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "hrinterface", "gradefromhr" );
                if (itemsToSave.Count > 0)
                {
                    int employeeid = itemsToSave[itemsToSave.Count - 1].EmployeeID;
                    int gradid = itemsToSave[itemsToSave.Count - 1].GradeID;
                    if (bvalid == false)
                    {
                        EmployeeDA.UpdateGradeSalary(tc, employeeid, gradid,
                            itemsToSave[itemsToSave.Count - 1].BasicSalary,
                            itemsToSave[itemsToSave.Count - 1].GrossSalary);
                        //    EmployeeDA.UpdateOTFlag(tc, employeeid);
                    }
                    else
                    {
                        EmployeeDA.UpdateSalary(tc, employeeid,
                            itemsToSave[itemsToSave.Count - 1].BasicSalary,
                            itemsToSave[itemsToSave.Count - 1].GrossSalary);
                        //  EmployeeDA.UpdateOTFlag(tc, employeeid);
                    }
                }
            }
            catch (Exception e)
            {
                #region Handle Exception

                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        public void Save2(TransactionContext tc, List<EmployeeGradeSalary> itemsToSave)
        {
            try
            {
                foreach (EmployeeGradeSalary item in itemsToSave)
                {
                    if (item.IsNew)
                    {
                        int id = tc.GenerateID("GRADESALARYASSIGNMENT", "EmpGradeSalaryID");
                        base.SetObjectID(item, id);
                        id = tc.GenerateID("GRADESALARYASSIGNMENT", "GradeSalaryID",
                            SQLParser.MakeSQL("WHERE EmployeeID=%n", item.EmployeeID));
                        item.EmployeeSerial = id;
                        EmployeeGradeSalaryDA.Insert(tc, item);
                    }
                    else
                    {
                        EmployeeGradeSalaryDA.Update(tc, item);
                    }
                }
            }
            catch (Exception e)
            {
                #region Handle Exception

                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        /// <summary>
        /// Arrer item delete
        /// </summary>
        /// <param name="gradeSalary"></param>
        public void Delete(EmployeeGradeSalary gradeSalary)
        {
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin(true);

                this.Delete(tc, gradeSalary);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        public void Delete(int pkid)
        {
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin(true);

                EmployeeGradeSalaryDA.Delete(tc, pkid);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        //Data Integration function
        public List<EmployeeGradeSalary> process(Employee oEmp, DateTime LastPayProcessDate, DateTime NextPayProcessDate,int currentUserId,EmployeeGradeSalary empGradeSalary)
        {
            List<EmployeeGradeSalary> itemstoSave = new List<EmployeeGradeSalary>();
            EmployeeGradeSalary item;
            //GradeSalaryChangeType effecttype = GradeSalaryChangeType.Get(this.GradeSalaryTypeID);
            // get the last (max on date) grade salary item  grade salary item from the database
            EmployeeGradeSalaryService gradeSalaryService = new EmployeeGradeSalaryService();
            // EmployeeGradeSalary lastgs = gradeSalaryService.GetMax(this.EmployeeID, EnumArrearType.NotPresent);
            EmployeeGradeSalary lastgs = gradeSalaryService.GetMax(empGradeSalary.EmployeeID, EnumArrearType.NotPresent);

            if (lastgs == null) // true is first time entry for the employee 
            {
                // if effect date befor the last payprocess date, a arrear item need to prepare
                //if (this.EffectDate <= SystemInformation.CurrentSysInfo.LastPayProcessDate)
                if (empGradeSalary.EffectDate <= LastPayProcessDate)
                {
                    //Create an arrear item 
                    //  item = (EmployeeGradeSalary)this.Clone();
                    item = empGradeSalary;
                    item.Employee = oEmp;
                    //item.EmployeeID = this.EmployeeID;
                    if (item.Employee.BasicSalary - item.BasicSalary > 1)
                        item.ArrearType = EnumArrearType.ToCalculate;
                    else
                    {
                        SalaryMonthlyService salaryMonthlyService = new SalaryMonthlyService();
                        // SalaryMonthly sm = SalaryMonthly.Get(item.EmployeeID, LastPayProcessDate);
                        SalaryMonthly sm = salaryMonthlyService.Get(item.EmployeeID, LastPayProcessDate);
                        if (sm == null)
                            item.ArrearType = EnumArrearType.ToCalculate;
                    }
                    // arrear item till date must be last payprocess date
                    item.TillDate = LastPayProcessDate;
                    itemstoSave.Add(item);

                    //  item = (EmployeeGradeSalary)this.Clone();
                    item = empGradeSalary;
                    //Normal item effect-date should be first date of the month and it will continue to next change
                    item.EffectDate = GlobalFunctions.FirstDateOfMonth(NextPayProcessDate);
                    item.TillDate = null;
                    item.ArrearType = EnumArrearType.NotPresent;
                    itemstoSave.Add(item);
                }
                else itemstoSave.Add(empGradeSalary);
            }
            else
            {
               // if (this.EffectDate > LastPayProcessDate)
                if(empGradeSalary.EffectDate > LastPayProcessDate)
                {
                    //lastgs.TillDate = this.EffectDate.AddDays(-1);
                    lastgs.TillDate = empGradeSalary.EffectDate.AddDays(-1);
                    itemstoSave.Add(lastgs);
                    //itemstoSave.Add(this);
                    itemstoSave.Add(empGradeSalary);
                }
                else
                {
                    #region do reverse process

                    //lastgs.TillDate = SystemInformation.CurrentSysInfo.LastPayProcessDate;
                    lastgs.TillDate = LastPayProcessDate;
                    itemstoSave.Add(lastgs);
                    // item = (EmployeeGradeSalary)this.Clone();
                    item = empGradeSalary;
                    item.Employee = oEmp;
                    item.ArrearType = EnumArrearType.ToCalculate;
                    // item.TillDate = SystemInformation.CurrentSysInfo.LastPayProcessDate;
                    item.TillDate = LastPayProcessDate;
                    itemstoSave.Add(item);
                    // update current item effect date
                    // this.EffectDate = SystemInformation.CurrentSysInfo.LastPayProcessDate.AddDays(1);
                    empGradeSalary.EffectDate = LastPayProcessDate.AddDays(1);
                    //itemstoSave.Add(this);
                    itemstoSave.Add(empGradeSalary);
                    #endregion
                }


            }
            foreach (EmployeeGradeSalary oitem in itemstoSave)
                oitem.SetAuditTrailProperties(DateTime.Today, currentUserId);
            return itemstoSave;
        }

        public void Delete(TransactionContext tc, EmployeeGradeSalary gradeSalary)
        {
            try
            {
                EmployeeGradeSalary updatedItem = null;
                if (gradeSalary.ArrearType != EnumArrearType.ToCalculate)
                {
                    EmployeeGradeSalaryService osvr = new EmployeeGradeSalaryService();
                    updatedItem = osvr.Get(tc, gradeSalary.EmployeeID,
                        gradeSalary.EffectDate.AddDays(-1), EnumArrearType.NotPresent);
                }

                if (updatedItem != null)
                {
                    updatedItem.TillDate = null;
                    updatedItem.ModifiedBy = gradeSalary.ModifiedBy;
                    updatedItem.ModifiedDate = DateTime.Today;
                    this.Delete(tc, updatedItem, gradeSalary);
                }
                else
                {
                    EmployeeGradeSalaryDA.Delete(tc, gradeSalary.EmployeeID, gradeSalary.EmployeeSerial);
                    if (gradeSalary.ArrearType != EnumArrearType.ToCalculate)
                    {
                        bool bvalid = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "hrinterface", "gradefromhr");
                        if (bvalid == false)
                            EmployeeDA.UpdateGradeSalary(tc, gradeSalary.EmployeeID,
                                0, 0, 0);
                        else
                            EmployeeDA.UpdateSalary(tc, gradeSalary.EmployeeID, 0, 0);
                    }
                }
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        public void DeleteAll()
        {
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin(true);
                EmployeeGradeSalaryDA.DeleteAll(tc);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        private void Delete(TransactionContext tc, EmployeeGradeSalary updateItem, EmployeeGradeSalary deletedItem)
        {
            try
            {
                EmployeeGradeSalaryDA.Update(tc, updateItem);
                EmployeeGradeSalaryDA.Delete(tc, deletedItem.EmployeeID, deletedItem.EmployeeSerial);

                bool bvalid =
                    new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "hrinterface", "gradefromhr");
                if (bvalid == false)
                    EmployeeDA.UpdateGradeSalary(tc, updateItem.EmployeeID,
                        updateItem.GradeID, updateItem.BasicSalary, updateItem.GrossSalary);
                else
                    EmployeeDA.UpdateSalary(tc, updateItem.EmployeeID, updateItem.BasicSalary, updateItem.GrossSalary);
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        public void DeleteFromDate(TransactionContext tc, int employeeId, DateTime effectDate, EnumArrearType arrtype)
        {
            try
            {
                EmployeeGradeSalaryDA.DeleteOnDate(tc, employeeId, effectDate, arrtype);
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        public void DeleteFrom(int employeeId, DateTime fromdate)
        {
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin(true);
                EmployeeGradeSalaryDA.DeleteFrom(tc, employeeId, fromdate);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        #endregion


        public List<EmployeeGradeSalary> process(TransactionContext tc, EmployeeGradeSalary ogradSalary, DateTime nextPayProcessDate,bool isTransferredReceived,
            bool multipleArrear = false)
        {
            List<EmployeeGradeSalary> itemstoSave = new List<EmployeeGradeSalary>();
            EmployeeGradeSalary item;
            GradeSalaryChangeTypeService gsctService = new GradeSalaryChangeTypeService();
            GradeSalaryChangeType effecttype = gsctService.Get(tc, ogradSalary.GradeSalaryTypeID);
            // get the last (max on date) grade salary item  grade salary item from the database
            EmployeeGradeSalary lastgs = this.GetMax(tc, ogradSalary.EmployeeID, EnumArrearType.NotPresent);
          
            if (lastgs == null) // true is first time entry for the employee 
            {
                // if effect date befor the last payprocess date, a arrear item need to prepare
                if (ogradSalary.EffectDate <= GlobalFunctions.LastPayProcessDate(nextPayProcessDate))
                {
                    //Create an arrear item 
                    item = ogradSalary.GetClone();
                    item.ArrearType = EnumArrearType.ToCalculate;
                    // arrear item till date must be last payprocess date
                    item.TillDate = GlobalFunctions.LastPayProcessDate(nextPayProcessDate);
                    itemstoSave.Add(item);

                    item = ogradSalary.GetClone();
                    //Normal item effect-date should be first date of the month and it will continue to next change
                    item.EffectDate = GlobalFunctions.FirstDateOfMonth(nextPayProcessDate);
                    item.TillDate = null;
                    item.ArrearType = EnumArrearType.NotPresent;
                    itemstoSave.Add(item);
                }
                else itemstoSave.Add(ogradSalary);
            }
            else
            {
                if (ogradSalary.EffectDate > GlobalFunctions.LastPayProcessDate(nextPayProcessDate))
                {
                    lastgs.TillDate = ogradSalary.EffectDate.AddDays(-1);
                    itemstoSave.Add(lastgs);
                    itemstoSave.Add(ogradSalary);
                }
                else
                {
                    #region do reverse process

                    // do reverse engineering 
                    if (multipleArrear == true)
                    {
                        List<EmployeeGradeSalary> savedItems =
                            this.GetbyTillDate(tc, ogradSalary.EmployeeID, ogradSalary.EffectDate,
                                GlobalFunctions.FirstDateOfMonth(nextPayProcessDate));
                        DateTime tempEffectDate = ogradSalary.EffectDate;

                        #region Do reverse engineering

                        int count = 1;
                        foreach (EmployeeGradeSalary arrerItem in savedItems)
                        {
                            //do not consider arrear to calculate item  
                            // because current save process will delete arrear calculate items first.
                            if (arrerItem.ArrearType == EnumArrearType.ToCalculate) continue;
                            if (arrerItem.EffectDate >= GlobalFunctions.LastPayProcessDate(nextPayProcessDate))
                                continue;
                            item = arrerItem.GetClone();
                            this.SetObjectState(item, Ease.Core.ObjectState.New);
                            item.EffectDate = (count == 1) ? ogradSalary.EffectDate : arrerItem.EffectDate;
                            item.ArrearType = EnumArrearType.ToCalculate;
                            item.GradeID = ogradSalary.GradeID;
                            item.BasicSalary = ogradSalary.BasicSalary;
                            item.GrossSalary = ogradSalary.GrossSalary;
                            item.PayScaleDetailID = ogradSalary.PayScaleDetailID;
                            item.GradeSalaryTypeID = ogradSalary.GradeSalaryTypeID;

                            item.TillDate = (arrerItem.TillDate == null)
                                ? GlobalFunctions.LastPayProcessDate(nextPayProcessDate)
                                : (DateTime)arrerItem.TillDate;
                            if (arrerItem.TillDate == null)
                            {
                                arrerItem.TillDate = GlobalFunctions.LastPayProcessDate(nextPayProcessDate);
                                itemstoSave.Add(arrerItem);
                            }

                            itemstoSave.Add(item);
                            count = count + 1;
                        }

                        #endregion

                        if (itemstoSave.Count == 0)
                        {
                            item = ogradSalary.GetClone();
                            item.ArrearType = EnumArrearType.ToCalculate;
                            // arrear item till date must be last payprocess date
                            item.TillDate = GlobalFunctions.LastPayProcessDate(nextPayProcessDate);
                            itemstoSave.Add(item);
                        }
                    }
                    else
                    {

                        if (!isTransferredReceived)
                                                    {
                            lastgs.TillDate = GlobalFunctions.LastPayProcessDate(nextPayProcessDate);
                            itemstoSave.Add(lastgs);
                            item = ogradSalary.GetClone();
                            item.ArrearType = EnumArrearType.ToCalculate;
                            item.TillDate = GlobalFunctions.LastPayProcessDate(nextPayProcessDate);
                            itemstoSave.Add(item);
                                                    }
                    }

                    // update current item effect date
                    ogradSalary.EffectDate = GlobalFunctions.LastPayProcessDate(nextPayProcessDate).AddDays(1);
                    itemstoSave.Add(ogradSalary);

                    #endregion
                }
            }

            foreach (EmployeeGradeSalary oitem in itemstoSave)
                oitem.SetAuditTrailProperties(DateTime.Today, ogradSalary.CreatedBy);
            return itemstoSave;
        }
    }
}