using HRM.BO;
using Ease.Core.DataAccess;
using Ease.Core.Model;
using Ease.Core.Utility;
using System;
using System.Collections.Generic;

namespace HRM.DA
{
    #region SettlmentAdvice Service

    public class SettlmentAdviceService : ServiceTemplate, ISettlementAdvanceService
    {
        #region Private functions and declaration

        public SettlmentAdviceService()
        {
        }

        private void MapObject(SettlmentAdvice oSettlmentAdvice, DataReader oReader)
        {
            base.SetObjectID(oSettlmentAdvice, oReader.GetInt32("SettlementAdviceID").Value);
            oSettlmentAdvice.TranDate = oReader.GetDateTime("TranDate").HasValue ? oReader.GetDateTime("TranDate").Value : DateTime.MinValue;
            oSettlmentAdvice.PaymentDate = oReader.GetDateTime("PaymentDate").HasValue ? oReader.GetDateTime("PaymentDate").Value : DateTime.MinValue;
            oSettlmentAdvice.SettlmentAdviceStatus = (EnumSettlmentAdviceStatus)oReader.GetInt32("SettlmentAdviceStatus").Value;
            oSettlmentAdvice.CreatedBy = oReader.GetInt32("CreatedBy") == null ? 0 : oReader.GetInt32("CreatedBy").Value;
            oSettlmentAdvice.CreatedDate = oReader.GetDateTime("CreatedDate").HasValue ? oReader.GetDateTime("CreatedDate").Value : DateTime.MinValue;
            oSettlmentAdvice.ModifiedBy = oReader.GetInt32("ModifiedBy") == null ? 0 : oReader.GetInt32("ModifiedBy").Value;
            oSettlmentAdvice.ModifiedDate = oReader.GetDateTime("ModifiedDate").HasValue ? oReader.GetDateTime("ModifiedDate").Value : DateTime.MinValue;
            this.SetObjectState(oSettlmentAdvice, Ease.Core.ObjectState.Saved);
        }

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

        private SettlmentAdvice CreateObject(DataReader oReader)
        {
            SettlmentAdvice oSettlmentAdvice = new SettlmentAdvice();
            MapObject(oSettlmentAdvice, oReader);
            return oSettlmentAdvice;
        }

        #endregion

        #region Service implementation
        public List<SettlmentAdvice> Get()
        {
            List<SettlmentAdvice> oSettlmentAdvice = new List<SettlmentAdvice>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader dr = new DataReader(SettlmentAdviceDA.Get(tc));
                oSettlmentAdvice = this.CreateObjects<SettlmentAdvice>(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 oSettlmentAdvice;
        }

        public SettlmentAdvice Get(int id)
        {
            SettlmentAdvice oSettlmentAdvice = new SettlmentAdvice();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader oreader = new DataReader(SettlmentAdviceDA.Get(tc, id));
                if (oreader.Read())
                {
                    oSettlmentAdvice = this.CreateObject<SettlmentAdvice>(oreader);
                }
                oreader.Close();
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException("Failed to Get SettlmentAdvice", e);

                #endregion
            }

            return oSettlmentAdvice;
        }

        public int Save(SettlmentAdvice oSettlmentAdvice)
        {
            int id = 0;
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin(true);
                if (oSettlmentAdvice.IsNew)
                {
                    id = tc.GenerateID("SettlmentAdvice", "SettlementAdviceID");
                    base.SetObjectID(oSettlmentAdvice, id);
                    SettlmentAdviceDA.Insert(tc, oSettlmentAdvice);
                }
                else
                {
                    SettlmentAdviceDA.Update(tc, oSettlmentAdvice);
                }

                SettlmentAdviceDA.DeleteByAdviceId(oSettlmentAdvice.ID, tc);
                if (oSettlmentAdvice.Items != null && oSettlmentAdvice.Items.Count > 0)
                {
                    foreach (var item in oSettlmentAdvice.Items)
                    {
                        //int itemId = tc.GenerateID("SettlmentAdviceItem", "SettlmentAdviceItemID");
                        item.SettlmentAdviceID = oSettlmentAdvice.ID;
                        SettlmentAdviceDA.InsertAdviceItem(tc, item);
                        SettlementClearanceDA.UpdateResignationStatus(tc, item.EmpResignID, EnumResignStatus.Payment_done);
                    }
                }
                //foreach(var item in oSettlmentAdvice.Items)
                //{
                //    SettlmentAdviceDA.UpdateItem(tc, item.SettlmentAdviceID,item.EmpResignID);
                //}

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

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new Exception("Failed to Insert SettlmentAdvice. Because " + e.Message, e);

                #endregion
            }
        }

        public void Delete(int id)
        {
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin(true);
                SettlmentAdviceDA.Delete(tc, id);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

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

                #endregion
            }
        }

        public List<SettlmentAdvice> GetByStatus(EnumSettlmentAdviceStatus saStatus)
        {
            List<SettlmentAdvice> oSettlmentAdvice = new List<SettlmentAdvice>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader dr = new DataReader(SettlmentAdviceDA.GetByStatus(tc, saStatus));
                oSettlmentAdvice = this.CreateObjects<SettlmentAdvice>(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 oSettlmentAdvice;
        }

        public List<SettlmentAdvice> GetByTranDate(DateTime sentDate)
        {
            List<SettlmentAdvice> oSettlmentAdvice = new List<SettlmentAdvice>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader dr = new DataReader(SettlmentAdviceDA.GetByTranDate(tc, sentDate));
                oSettlmentAdvice = this.CreateObjects<SettlmentAdvice>(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 oSettlmentAdvice;
        }

        public List<SettlmentAdvice> Get(DateTime fromSentDate, DateTime toSentDate)
        {
            List<SettlmentAdvice> oSettlmentAdvice = new List<SettlmentAdvice>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader dr = new DataReader(SettlmentAdviceDA.Get(tc, fromSentDate, toSentDate));
                oSettlmentAdvice = this.CreateObjects<SettlmentAdvice>(dr);
                dr.Close();
                if (oSettlmentAdvice != null)
                {

                    List<SettlmentAdvice.SettlmentAdviceItem> items = new List<SettlmentAdvice.SettlmentAdviceItem>();
                    dr = new DataReader(SettlmentAdviceDA.GetDetail(tc, fromSentDate, toSentDate));
                    while (dr.Read())
                    {
                        SettlmentAdvice.SettlmentAdviceItem item = new SettlmentAdvice.SettlmentAdviceItem();

                        item.SettlmentAdviceID = dr.GetInt32("SettlementAdviceID").Value;
                        item.EmpResignID = dr.GetInt32("EmpResignID").Value;
                        items.Add(item);
                    }
                    dr.Close();

                    if(items.Count !=0)
                    {
                        foreach(SettlmentAdvice ad in oSettlmentAdvice)
                        {
                            ad.Items = items.FindAll(x => x.SettlmentAdviceID == ad.ID);
                        }
                    }
                }
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception
                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);
                #endregion
            }

            return oSettlmentAdvice;
        }

        public List<SettlmentAdvice> GetByPaymentDate(DateTime clearanceDate)
        {
            List<SettlmentAdvice> oSettlmentAdvice = new List<SettlmentAdvice>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader dr = new DataReader(SettlmentAdviceDA.GetByPaymentDate(tc, clearanceDate));
                oSettlmentAdvice = this.CreateObjects<SettlmentAdvice>(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 oSettlmentAdvice;
        }

        public List<SettlmentAdvice> GetByPaymentDateRange(DateTime fromClearanceDate, DateTime toClearanceDate)
        {
            List<SettlmentAdvice> oSettlmentAdvice = new List<SettlmentAdvice>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader dr = new DataReader(SettlmentAdviceDA.GetByPaymentDateRange(tc, fromClearanceDate, toClearanceDate));
                oSettlmentAdvice = this.CreateObjects<SettlmentAdvice>(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 oSettlmentAdvice;
        }
        #endregion
    }

    #endregion
}