using LHDN.CRM.BC.Common;
using LHDN.CRM.BC.Repositories;
using LHDN.CRM.Models.ViewModels;
using LHDN.CRM.Models.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Newtonsoft.Json.Linq;

namespace LHDN.CRM.BC.Services
{
    public class OutboundService
    {
        private OutboundRepository repo = new OutboundRepository();
        private GeneralRepository repoGeneral = new GeneralRepository();
        private UserProfileService userSVC = new UserProfileService();

        public DropdownViewModel GetDropdown(bool blnIsHCLEmailBlast)
        {
            DropdownViewModel ddlVM = new DropdownViewModel();
            if (blnIsHCLEmailBlast)
            {
                ddlVM.JenisKempenOptions = Utilities.SortDDL(AdminService.JenisKempens.Where(x => x.JenisKempenKategoriSysID == 26 && x.IsActive == true) //exclude KempenHCL
                                                    .Select(x => new DropdownDetailViewModel
                                                    {
                                                        Value = x.JenisKempenID,
                                                        Text = x.JenisKempenName
                                                    }).ToList());
                ddlVM.SegmentiseActChannelOptions = AdminService.ActivityChannels.Where(x => x.ActChannelID == 2).ToList();  // Order at js
                ddlVM.OutboundViewOptions = repo.GetEmailBlastViewDDL(userSVC.UserInfo.UserProfileID);
                ddlVM.CCCampaignOption = Utilities.SortDDL(AdminService.LookupParams.Where(x => x.LookupCode == "CCCampaignHCL" && x.IsActive == true).Select(x => new DropdownDetailViewModel { Value = x.LookupParamID, Text = x.ParamDesc, Code = x.LookupValue, IsDefault = x.IsDefault }).ToList());
                ddlVM.CCTemplateOption = AdminService.CCTemplate.Where(x => x.IsActive == true && x.CCTemplateType == "E").ToList();
            }
            else
            {
                ddlVM.JenisKempenOptions = Utilities.SortDDL(AdminService.JenisKempens.Where(x => x.JenisKempenKategoriSysID != 26 && x.IsActive == true) //exclude KempenHCL
                                                                    .Select(x => new DropdownDetailViewModel
                                                                    {
                                                                        Value = x.JenisKempenID,
                                                                        Text = x.JenisKempenName
                                                                    }).ToList());
                ddlVM.SegmentiseActChannelOptions = AdminService.ActivityChannels.Where(x => x.ActChannelID == 2 || x.ActChannelID == 5 || x.ActChannelID == 6).ToList();  // Order at js
                ddlVM.OutboundViewOptions = repo.GetOutboundViewDDL(userSVC.UserInfo.UserProfileID).ToList();
                ddlVM.CCCampaignOption = Utilities.SortDDL(AdminService.LookupParams.Where(x => x.LookupCode == "CCCampaign" && x.IsActive == true).Select(x => new DropdownDetailViewModel { Value = x.LookupParamID, Text = x.ParamDesc, Code = x.LookupValue, IsDefault = x.IsDefault }).ToList());
                ddlVM.CCTemplateOption = AdminService.CCTemplate.Where(x => x.IsActive == true).ToList();
            }
            ddlVM.JenisPengenalanOptions = Utilities.SortDDL(AdminService.LookupParams.Where(x => x.LookupCode == "JenisPengenalan" && x.IsActive == true).Select(x => new DropdownDetailViewModel { Value = x.LookupParamID, Text = x.ParamDesc, IsDefault = x.IsDefault }).ToList());

            ddlVM.ActChannelOptions = AdminService.ActivityChannels.ToList();  // Order at js
            ddlVM.MainKategoriOptions = AdminService.Kategoris.Where(x => x.IsActive == true).ToList<MainKategori>(); // Order at js 
            ddlVM.AliranOptions = AdminService.LookupParams.Where(x => x.LookupCode == "Aliran" && x.IsActive == true)
                                .Select(x => new DropdownDetailViewModel
                                {
                                    Value = x.LookupParamID,
                                    Text = x.ParamDesc,
                                    IsDefault = x.IsDefault,
                                    Code = x.LookupValue
                                }).ToList();
            ddlVM.ActStatusOptions = AdminService.LookupParams.Where(x => x.LookupCode == "ActivityStatus" && x.IsActive == true)
                                .Select(x => new DropdownDetailViewModel
                                {
                                    Value = x.LookupParamID,
                                    Text = x.ParamDesc,
                                    IsDefault = x.IsDefault,
                                    Code = x.LookupValue
                                }).ToList();
            ddlVM.OutboundStatusOption = AdminService.LookupParamSys.Where(x => x.LookupCode == "OutboundStatus").Select(x => new DropdownDetailViewModel
            {
                Value = x.LookupParamSysID,
                Text = x.ParamDesc
            }).ToList();
            ddlVM.CCFromEmailOption = Utilities.SortDDL(AdminService.LookupParams.Where(x => x.LookupCode == "CCFromEmail" && x.IsActive == true).Select(x => new DropdownDetailViewModel { Value = x.LookupParamID, Text = x.ParamDesc, Code = x.LookupValue, IsDefault = x.IsDefault }).ToList());
            ddlVM.CCFromSMSOption = Utilities.SortDDL(AdminService.LookupParams.Where(x => x.LookupCode == "CCFromSMS" && x.IsActive == true).Select(x => new DropdownDetailViewModel { Value = x.LookupParamID, Text = x.ParamDesc, Code = x.LookupValue, IsDefault = x.IsDefault }).ToList());
            ddlVM.ParameterSettings = AdminService.ParameterSettings.Where(x => (x.ParameterID == 14 || x.ParameterID == 22)).ToList<ParameterSettings>();

            return ddlVM;
        }

        public List<SearchSavedViewViewModel> GetOutboundSavedViewColumns(SearchOutboundPagedListViewModel model)
        {
            if (model.IsHCLEmailBlast == true)
            {
                return repo.GetEmailBlastSavedViewColumns(model.ViewID, model.JenisKempenID.Value,
                    model.IsDynamicDisplayColumn, model.DisplayColumns);
            }
            else
            {
                return repo.GetOutboundSavedViewColumns(model.ViewID, model.JenisKempenID.Value,
                    model.IsDynamicDisplayColumn, model.DisplayColumns);
            }
        }

        public dynamic SearchOutboundSavedView(SearchOutboundPagedListViewModel paging, out int intCount, out int intCountNew
                                            , out int intCountVerified, out int intCountScheduled)
        {
            intCount = 0;
            intCountNew = 0;
            intCountVerified = 0;
            intCountScheduled = 0;

            DataSet ds;

            //Format datetime
            //if (paging.Rules != null)
            //{
            //    foreach (AdvanceRulesViewModel rule in paging.Rules)
            //    {
            //        foreach (RuleGroupViewModel ruleGroup in rule.RuleGroup)
            //        {
            //            if (ruleGroup.FieldType == 14)
            //            {
            //                ruleGroup.FieldValues[0].FieldValue = Convert.ToDateTime(ruleGroup.FieldValues[0].FieldValue, CultureInfo.InvariantCulture);
            //            }
            //        }
            //    }
            //}

            if (paging.IsHCLEmailBlast == true)
            {
                ds = repo.GetSearchEmailBlastResult(paging);
            }
            else
            {
                ds = repo.GetSearchOutboundResult(paging);
            }

            object lst = new List<SearchTPResultViewModel>();

            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lst = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(ds.Tables[0]));
                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
                if (paging.IsReturnCount == true)
                {
                    if (ds.Tables[2] != null && ds.Tables[2].Rows.Count > 0)
                        intCountNew = Convert.ToInt32(ds.Tables[2].Rows[0][0].ToString());
                    if (ds.Tables[3] != null && ds.Tables[3].Rows.Count > 0)
                        intCountVerified = Convert.ToInt32(ds.Tables[3].Rows[0][0].ToString());
                    if (ds.Tables[4] != null && ds.Tables[4].Rows.Count > 0)
                        intCountScheduled = Convert.ToInt32(ds.Tables[4].Rows[0][0].ToString());
                }
            }

            return lst;
        }

        public dynamic GetOutboundDetails(OutboundParamViewModel vm)
        {
            if (vm.DataID == 0 || vm.JenisKempenID == 0)
            {
                throw new NotFoundException("Jenis Kempen ID or ReMS Data ID is invalid!");
            }

            JenisKempenDetailViewModel objJenisKempenDetails = repo.GetJenisKempenDetailByID((int)vm.JenisKempenID, 0);

            if (objJenisKempenDetails == null)
            {
                throw new NotFoundException("Jenis kempen kategori not found!");
            }

            dynamic obj = null;
            switch (objJenisKempenDetails.JenisKempenKategoriSysID)
            {
                case ((int)Constant.KempenKategori.KesTunggakan):
                    obj = repo.GetOutboundDetailsTunggakan(objJenisKempenDetails.ReMSTableName, (int)vm.JenisKempenID, (long)vm.DataID);
                    break;
                case ((int)Constant.KempenKategori.KesAnsuran):
                    obj = repo.GetOutboundDetailsAnsuran(objJenisKempenDetails.ReMSTableName, (int)vm.JenisKempenID, (long)vm.DataID);
                    break;
                case ((int)Constant.KempenKategori.KesCTL):
                    obj = repo.GetOutboundDetailsCTL(objJenisKempenDetails.ReMSTableName, (int)vm.JenisKempenID, (long)vm.DataID);
                    break;
            }

            if (obj == null)
            {
                throw new NotFoundException("Outbound details not found!");
            }

            obj.JenisKempenDetails = objJenisKempenDetails;
            obj.ReturnedReasonOptions = Utilities.SortDDL(AdminService.LookupParams.Where(x => x.LookupCode == "ReturnedReason" && x.IsActive == true).Select(x => new DropdownDetailViewModel { Value = x.LookupParamID, Text = x.ParamDesc, IsDefault = x.IsDefault, Code = x.LookupValue, SeqNo = x.SeqNo }).ToList());
            obj.KodSelesaiReturnDesc = AdminService.KodSelesai.Where(x => x.KodSelesaiID == 31).ToList().FirstOrDefault()?.KodSelesaiDesc;

            return obj;
        }

        public List<ChangeHistoryUpdateViewModel> UpdateOutboundDetailsAnsuran(OutboundDetailsAnsuranUpdateViewModel vm, out string strOldStatus)
        {
            List<ChangeHistoryUpdateViewModel> lst = new List<ChangeHistoryUpdateViewModel>();

            // Retrieve orginal records for audit and change history 
            OutboundParamViewModel model = new OutboundParamViewModel();
            model.DataID = vm.OutboundDetails.DataID;
            model.JenisKempenID = vm.OutboundDetails.JenisKempenID;

            OutboundDetailsAnsuranViewModel oriOutboundDetails = GetOutboundDetails(model);
            strOldStatus = AdminService.LookupParamSys.Where(x => x.LookupParamSysID == oriOutboundDetails.StatusID).FirstOrDefault()?.ParamDesc;

            // 1. Check for update conflict
            //if (!Utilities.CompareByteArray(vm.OutboundDetails.ChangeStamp, oriOutboundDetails.ChangeStamp))
            //{
            //    throw new UpdateConflictException();
            //}

            int i = repo.UpdateOutboundDetailsAnsuran(vm.OutboundDetails);
            if (vm.blnIsVerify == true)
            {
                List<OutboundUpdateViewModel> lstOutboundDetails = new List<OutboundUpdateViewModel>();
                JenisKempenDetailViewModel objJenisKempenDetails = new JenisKempenDetailViewModel();

                lstOutboundDetails.Add(new OutboundUpdateViewModel { ReMSDataID = vm.OutboundDetails.DataID });
                objJenisKempenDetails = repo.GetJenisKempenDetailByID(vm.OutboundDetails.JenisKempenID.Value, 0);

                long j = repo.UpdateOutboundReMSStatus(lstOutboundDetails, objJenisKempenDetails.ReMSTableName, (int)Constant.OutboundStatus.Disahkan, vm.OutboundDetails.LastUpdatedBy, vm.OutboundDetails.LastUpdatedByName, vm.OutboundDetails.LastUpdatedDateTime);
            }

            // 3.Get ChangeHistory
            foreach (ChangeHistoryUpdateViewModel changeHistoryItem in vm.ChangeHistory)
            {
                //Get object original value
                string strOriValue = string.Empty;

                var obj = Utilities.GetPropertyValue(oriOutboundDetails, changeHistoryItem.FieldName);

                if (obj != null)
                {
                    switch (obj.GetType().Name)
                    {
                        case "DateTime":
                            strOriValue = Convert.ToDateTime(obj).ToString("dd MMM yyyy");
                            break;
                        case "Boolean":
                            bool flag = (bool)obj;
                            if (flag == true)
                                strOriValue = "Ya";
                            else
                                strOriValue = "Tidak";
                            break;
                        case "Decimal":
                            strOriValue = String.Format("{0:N}", Convert.ToDouble(obj));
                            break;
                        default:
                            strOriValue = obj.ToString();
                            break;
                    }
                }

                changeHistoryItem.OldValue = strOriValue;

                //if ((changeHistoryItem.FieldName == "ACCOUNT_START_DATE" || changeHistoryItem.FieldName == "ACCOUNT_END_DATE" || changeHistoryItem.FieldName == "AMEN_SHED_DATE"
                //    || changeHistoryItem.FieldName == "MIN_DUE_DATE" || changeHistoryItem.FieldName == "SKIM_DATE" || changeHistoryItem.FieldName == "TarikhKenaBayar") && !string.IsNullOrEmpty(oriValue))
                //    changeHistoryItem.OldValue = Convert.ToDateTime(OriValue).ToString("dd MMM yyyy");

                //if ((changeHistoryItem.FieldName == "TOTAL_AMOUNT" || changeHistoryItem.FieldName == "JUM_PERLU_BYR" || changeHistoryItem.FieldName == "MAX_DUE_AMOUNT") && !string.IsNullOrEmpty(oriValue))
                //    changeHistoryItem.OldValue = String.Format("{0:N}", Convert.ToDouble(OriValue));

                changeHistoryItem.IsChanged = !(changeHistoryItem.OldValue == changeHistoryItem.NewValue);
            }

            lst = InsertChangeHistory(vm.ChangeHistory, vm.OutboundDetails.LastUpdatedByName, vm.OutboundDetails.LastUpdatedBy, vm.OutboundDetails.LastUpdatedDateTime);

            return lst;
        }


        public List<ChangeHistoryUpdateViewModel> UpdateOutboundDetailsTunggakan(OutboundDetailsTunggakanUpdateViewModel vm, out string strOldStatus)
        {
            List<ChangeHistoryUpdateViewModel> lst = new List<ChangeHistoryUpdateViewModel>();

            // Retrieve orginal records for audit and change history 
            OutboundParamViewModel model = new OutboundParamViewModel();
            model.DataID = vm.OutboundDetails.DataID;
            model.JenisKempenID = vm.OutboundDetails.JenisKempenID;

            OutboundDetailsTunggakanViewModel oriOutboundDetails = GetOutboundDetails(model);
            strOldStatus = AdminService.LookupParamSys.Where(x => x.LookupParamSysID == oriOutboundDetails.StatusID).FirstOrDefault()?.ParamDesc;

            // 1. Check for update conflict
            //if (!Utilities.CompareByteArray(vm.OutboundDetails.ChangeStamp, oriOutboundDetails.ChangeStamp))
            //{
            //    throw new UpdateConflictException();
            //}

            int i = repo.UpdateOutboundDetailsTunggakan(vm.OutboundDetails);
            if (vm.blnIsVerify == true)
            {
                List<OutboundUpdateViewModel> lstOutboundDetails = new List<OutboundUpdateViewModel>();
                JenisKempenDetailViewModel objJenisKempenDetails = new JenisKempenDetailViewModel();

                lstOutboundDetails.Add(new OutboundUpdateViewModel { ReMSDataID = vm.OutboundDetails.DataID });
                objJenisKempenDetails = repo.GetJenisKempenDetailByID(vm.OutboundDetails.JenisKempenID.Value, 0);

                long j = repo.UpdateOutboundReMSStatus(lstOutboundDetails, objJenisKempenDetails.ReMSTableName, (int)Constant.OutboundStatus.Disahkan, vm.OutboundDetails.LastUpdatedBy, vm.OutboundDetails.LastUpdatedByName, vm.OutboundDetails.LastUpdatedDateTime);
            }

            // 3.Get ChangeHistory
            foreach (ChangeHistoryUpdateViewModel changeHistoryItem in vm.ChangeHistory)
            {
                //Get object original value
                string strOriValue = string.Empty;

                var obj = Utilities.GetPropertyValue(oriOutboundDetails, changeHistoryItem.FieldName);
                if (obj != null)
                {
                    switch (obj.GetType().Name)
                    {
                        case "DateTime":
                            strOriValue = Convert.ToDateTime(obj).ToString("dd MMM yyyy");
                            break;
                        case "Boolean":
                            bool flag = (bool)obj;
                            if (flag == true)
                                strOriValue = "Ya";
                            else
                                strOriValue = "Tidak";
                            break;
                        case "Decimal":
                            strOriValue = String.Format("{0:N}", Convert.ToDouble(obj));
                            break;
                        default:
                            strOriValue = obj.ToString();
                            break;
                    }
                }

                changeHistoryItem.OldValue = strOriValue;

                //if ((changeHistoryItem.FieldName == "ASSESSMENT_DATE" || changeHistoryItem.FieldName == "PAYMENT_DUE_DATE" || changeHistoryItem.FieldName == "PINK_LETTER_DATE") && !string.IsNullOrEmpty(oriValue))
                //    changeHistoryItem.OldValue = Convert.ToDateTime(oriValue).ToString("dd MMM yyyy");

                //if ((changeHistoryItem.FieldName == "ASSESSMENT_AMOUNT" || changeHistoryItem.FieldName == "SUM_BAL" || changeHistoryItem.FieldName == "PINK_LETTER_AMT") && !string.IsNullOrEmpty(oriValue))
                //    changeHistoryItem.OldValue = String.Format("{0:N}", Convert.ToDouble(oriValue));

                changeHistoryItem.IsChanged = !(changeHistoryItem.OldValue == changeHistoryItem.NewValue);
            }

            lst = InsertChangeHistory(vm.ChangeHistory, vm.OutboundDetails.LastUpdatedByName, vm.OutboundDetails.LastUpdatedBy, vm.OutboundDetails.LastUpdatedDateTime);

            return lst;
        }

        public List<ChangeHistoryUpdateViewModel> UpdateOutboundDetailsCTL(OutboundDetailsCTLUpdateViewModel vm, out string strOldStatus)
        {
            List<ChangeHistoryUpdateViewModel> lst = new List<ChangeHistoryUpdateViewModel>();

            // Retrieve orginal records for audit and change history 
            OutboundParamViewModel model = new OutboundParamViewModel();
            model.DataID = vm.OutboundDetails.DataID;
            model.JenisKempenID = vm.OutboundDetails.JenisKempenID;

            OutboundDetailsCTLViewModel oriOutboundDetails = GetOutboundDetails(model);
            strOldStatus = AdminService.LookupParamSys.Where(x => x.LookupParamSysID == oriOutboundDetails.StatusID).FirstOrDefault()?.ParamDesc;

            // 1. Check for update conflict
            //if (!Utilities.CompareByteArray(vm.OutboundDetails.ChangeStamp, oriOutboundDetails.ChangeStamp))
            //{
            //    throw new UpdateConflictException();
            //}

            int i = repo.UpdateOutboundDetailsCTL(vm.OutboundDetails);
            if (vm.blnIsVerify == true)
            {
                List<OutboundUpdateViewModel> lstOutboundDetails = new List<OutboundUpdateViewModel>();
                JenisKempenDetailViewModel objJenisKempenDetails = new JenisKempenDetailViewModel();

                lstOutboundDetails.Add(new OutboundUpdateViewModel { ReMSDataID = vm.OutboundDetails.DataID });
                objJenisKempenDetails = repo.GetJenisKempenDetailByID(vm.OutboundDetails.JenisKempenID.Value, 0);

                long j = repo.UpdateOutboundReMSStatus(lstOutboundDetails, objJenisKempenDetails.ReMSTableName, (int)Constant.OutboundStatus.Disahkan, vm.OutboundDetails.LastUpdatedBy, vm.OutboundDetails.LastUpdatedByName, vm.OutboundDetails.LastUpdatedDateTime);
            }
            // 3.Get ChangeHistory
            foreach (ChangeHistoryUpdateViewModel changeHistoryItem in vm.ChangeHistory)
            {
                //Get object original value
                string strOriValue = string.Empty;

                var obj = Utilities.GetPropertyValue(oriOutboundDetails, changeHistoryItem.FieldName);
                if (obj != null)
                {
                    switch (obj.GetType().Name)
                    {
                        case "DateTime":
                            strOriValue = Convert.ToDateTime(obj).ToString("dd MMM yyyy");
                            break;
                        case "Boolean":
                            bool flag = (bool)obj;
                            if (flag == true)
                                strOriValue = "Ya";
                            else
                                strOriValue = "Tidak";
                            break;
                        case "Decimal":
                            strOriValue = String.Format("{0:N}", Convert.ToDouble(obj));
                            break;
                        default:
                            strOriValue = obj.ToString();
                            break;
                    }
                }

                changeHistoryItem.OldValue = strOriValue;

                //if ((changeHistoryItem.FieldName == "CTL_DATE" || changeHistoryItem.FieldName == "DATE_BANK_IN" || changeHistoryItem.FieldName == "DATE_BANK_INVALID"
                //    || changeHistoryItem.FieldName == "DATE_CEK_ACCEPT") && !string.IsNullOrEmpty(oriValue))
                //    changeHistoryItem.OldValue = Convert.ToDateTime(oriValue).ToString("dd MMM yyyy");

                //if (changeHistoryItem.FieldName == "CEK_NO" && !string.IsNullOrEmpty(oriValue))
                //    changeHistoryItem.OldValue = String.Format("{0:N}", Convert.ToDouble(oriValue));

                changeHistoryItem.IsChanged = !(changeHistoryItem.OldValue == changeHistoryItem.NewValue);
            }

            lst = InsertChangeHistory(vm.ChangeHistory, vm.OutboundDetails.LastUpdatedByName, vm.OutboundDetails.LastUpdatedBy, vm.OutboundDetails.LastUpdatedDateTime);

            return lst;
        }

        public List<OutboundManualAssignedPagedListViewModel> GetOutboundManualAssigned(OutboundManualAssignedPagedListViewModel paging, out int intCount)
        {
            intCount = 0;
            DataSet ds = repo.GetOutboundManualAssigned(paging);

            List<OutboundManualAssignedPagedListViewModel> lstOutboundManualAssign = new List<OutboundManualAssignedPagedListViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstOutboundManualAssign = repo.DataTableToList<OutboundManualAssignedPagedListViewModel>(ds.Tables[0]).ToList();
                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstOutboundManualAssign;
        }

        public OutboundManualAssignedPagedListViewModel UpdatedOCLAgentAssign(OutboundUser user, OutboundManualAssignedPagedListViewModel paging, DateTime dtNow)
        {
            JenisKempenDetailViewModel JenisKempenDetail = new JenisKempenDetailViewModel();

            OutboundManualAssignedPagedListViewModel data = repo.GetManualAgentAssignByID(paging, dtNow);
            JenisKempenDetail = repo.GetJenisKempenDetailByID(data.JenisKempenID, 0);
            if (JenisKempenDetail != null)
            {
                var RemsTableName = JenisKempenDetail.ReMSTableName;
                //Check Auto Pick Outbound Manual List has been assign or not.
                OutboundUser Usermodel = repo.CheckReMsTableForManualOutboundAssign(RemsTableName, data.JenisKempenID, data.DataID);
                if (Usermodel.ID == "")
                {
                    string strRemark = "Auto Picked Up";
                    repo.UpdatedRemsTableForManualAssigned(RemsTableName, data.JenisKempenID, data.DataID, user, user, strRemark, dtNow);
                }
                else
                {
                    data.DataID = -1;
                }


            }
            return data;
        }


        public List<OutboundUser> GetAllUser(OutboundUser data)
        {
            List<OutboundUser> AllUser = new List<OutboundUser>();
            AllUser = repo.GetAllUser(data);

            return AllUser;
        }

        public OutboundManualAssignUpdatedModel UpdatedOCLMangerAssign(OutboundManualAssignUpdatedModel data, OutboundUser assignedUser, OutboundUser CurrentLoginUser, DateTime dtNow)
        {
            string strRemark = "";
            int CountHavenAssign = 0;
            int CountHasAssign = 0;
            if (data.Remark == null)
            {
                strRemark = "";
            }
            else
            {
                strRemark = data.Remark;
            }

            data.Outbound = UpdatedOutboundDetail(data.Outbound, assignedUser, CurrentLoginUser, strRemark, dtNow, out CountHavenAssign, out CountHasAssign);
            data.CountAlreadyAssignBeforeManualAssign = CountHasAssign;
            data.CountHavenAssignBeforeManualAssign = CountHavenAssign;

            return data;
        }

        public List<OutboundUpdateViewModel> UpdatedOutboundDetail(List<OutboundUpdateViewModel> model, OutboundUser assignedUser, OutboundUser CurrentLoginUser, string strRemark, DateTime dtNow, out int CountHavenAssign, out int CountHasAssign)
        {
            JenisKempenDetailViewModel JenisKempenDetail = new JenisKempenDetailViewModel();
            List<OutboundUpdateViewModel> lst = model.ToList();
            DataSet ds = repo.GetManualManagerAssignedByID(lst, assignedUser, CurrentLoginUser, strRemark, dtNow);
            int j = 0;  //Used for already has assign user.
            int k = 0; //Used for haven assign user
            CountHavenAssign = 0;
            CountHasAssign = 0;

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lst = repo.DataTableToList<OutboundUpdateViewModel>(ds.Tables[0]).ToList();

                //Updated Rems Table
                for (int i = 0; i < lst.Count; i++)
                {
                    JenisKempenDetail = repo.GetJenisKempenDetailByID(lst[i].JenisKempenId, 0);
                    if (JenisKempenDetail != null)
                    {
                        var RemsTableName = JenisKempenDetail.ReMSTableName;
                        //Check Auto Pick Outbound Manual List has been assign or not.
                        OutboundUser Usermodel = repo.CheckReMsTableForManualOutboundAssign(RemsTableName, lst[i].JenisKempenId, lst[i].ReMSDataID);
                        if (Usermodel.ID == "")
                        {
                            repo.UpdatedRemsTableForManualAssigned(RemsTableName, lst[i].JenisKempenId, lst[i].ReMSDataID, assignedUser, CurrentLoginUser, strRemark, dtNow);
                            //Haven Assign to anyone before Outbound Assignment.
                            k = k + 1;
                        }
                        else
                        {
                            //Already Assign before Outbound Assignment.
                            j = j + 1;
                        }
                    }
                }
                CountHavenAssign = k;
                CountHasAssign = j;
            }

            return lst;
        }

        public List<OutboundManualAssignedPagedListViewModel> GetMyPendingOutboundInDashboard(string CurrentUserId, OutboundManualAssignedPagedListViewModel paging, out int intCount)
        {
            intCount = 0;
            DataSet ds = repo.GetMyPendingOutboundInDashboard(CurrentUserId, paging);

            List<OutboundManualAssignedPagedListViewModel> lstMyDashboardOutbound = new List<OutboundManualAssignedPagedListViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstMyDashboardOutbound = repo.DataTableToList<OutboundManualAssignedPagedListViewModel>(ds.Tables[0]).ToList();
                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstMyDashboardOutbound;
        }



        public OutboundSegmentiseViewModel GetOutboundSegmentise(long lngViewID)
        {
            OutboundSegmentiseViewModel vm = null;

            vm = repo.GetOutboundSegmentise(lngViewID);

            if (vm != null)
            {
                vm.Campaign = repo.GetOutboundCampaign(lngViewID, 0);
            }


            return vm;
        }

        public OutboundSegmentiseViewModel GetEmailBlastSegmentise(long lngViewID)
        {
            OutboundSegmentiseViewModel vm = null;

            vm = repo.GetEmailBlastSegmentise(lngViewID);

            if (vm != null)
            {
                vm.Campaign = repo.GetEmailBlastCampaign(lngViewID, 0);
            }


            return vm;
        }

        public OutboundSegmentiseUpdateViewModel UpdateOutboundSegmentise(OutboundSegmentiseUpdateViewModel vm, string strLastUpdatedBy, DateTime dtLastUpdatedDateTime,
                                                            out long lngViewID, out int intCampaignID)
        {
            OutboundSegmentiseUpdateViewModel lst = new OutboundSegmentiseUpdateViewModel();
            lngViewID = 0;
            intCampaignID = 0;

            List<AdvanceRulesViewModel> lstViewRule = new List<AdvanceRulesViewModel>();
            List<RuleGroupViewModel> lstViewRuleGroup = new List<RuleGroupViewModel>();
            List<FieldValueViewModel> lstViewRuleGroupFields = new List<FieldValueViewModel>();

            vm.AdvancedRules.Rules = Utilities.GenerateRowIDForAdvanceRules(vm.AdvancedRules.Rules, vm.OutboundSegmentise.IsBasicMode.Value);

            foreach (AdvanceRulesViewModel item in vm.AdvancedRules.Rules)
            {
                AdvanceRulesViewModel vmViewRule = new AdvanceRulesViewModel();
                vmViewRule.ViewRuleID = item.ViewRuleID;
                vmViewRule.RuleType = item.RuleType;
                vmViewRule.RuleOperator = item.RuleOperator;
                vmViewRule.GroupingOperator = item.GroupingOperator;
                vmViewRule.Sequence = item.Sequence;
                vmViewRule.IsFromDB = item.IsFromDB;

                lstViewRule.Add(vmViewRule);

                foreach (RuleGroupViewModel itemRuleGrp in item.RuleGroup)
                {
                    RuleGroupViewModel vmViewRuleGroup = new RuleGroupViewModel();
                    vmViewRuleGroup.ViewRuleGroupID = itemRuleGrp.ViewRuleGroupID;
                    vmViewRuleGroup.ViewRuleID = itemRuleGrp.ViewRuleID;
                    vmViewRuleGroup.FieldMapping = itemRuleGrp.FieldMapping;
                    vmViewRuleGroup.FieldOperator = itemRuleGrp.FieldOperator;
                    vmViewRuleGroup.IsFromDB = itemRuleGrp.IsFromDB;
                    //vmViewRuleGroup.IsFromDB = vmViewRule.IsFromDB;

                    lstViewRuleGroup.Add(vmViewRuleGroup);

                    foreach (FieldValueViewModel itemFieldValue in itemRuleGrp.FieldValues)
                    {
                        FieldValueViewModel vmViewRuleGroupFields = new FieldValueViewModel();
                        vmViewRuleGroupFields.ViewRuleGroupFieldsID = itemFieldValue.ViewRuleGroupFieldsID;
                        vmViewRuleGroupFields.ViewRuleGroupID = itemFieldValue.ViewRuleGroupID;
                        vmViewRuleGroupFields.FieldValue = itemFieldValue.FieldValue;
                        vmViewRuleGroupFields.IsFromDB = itemFieldValue.IsFromDB;
                        //vmViewRuleGroupFields.IsFromDB = vmViewRule.IsFromDB;
                        lstViewRuleGroupFields.Add(vmViewRuleGroupFields);
                    }
                }
            }

            DataTable dTblResultSeg = new DataTable();

            if (vm.IsHCLEmailBlast == true)
                dTblResultSeg = repo.UpdateEmailBlastSegmentise(vm.OutboundSegmentise, lstViewRule, lstViewRuleGroup, lstViewRuleGroupFields,
                                                                vm.AdvancedRules.DisplaySetting?.DisplayColumns?.ToList(),
                                                                 vm.AdvancedRules.DisplaySetting?.FieldsSorting?.ToList(),
                                                                 strLastUpdatedBy, dtLastUpdatedDateTime);
            else
                dTblResultSeg = repo.UpdateOutboundSegmentise(vm.OutboundSegmentise, lstViewRule, lstViewRuleGroup, lstViewRuleGroupFields,
                                                                vm.AdvancedRules.DisplaySetting?.DisplayColumns?.ToList(),
                                                                vm.AdvancedRules.DisplaySetting?.FieldsSorting?.ToList(),
                                                                strLastUpdatedBy, dtLastUpdatedDateTime);


            if (dTblResultSeg != null && dTblResultSeg.Rows.Count > 0)
            {
                lngViewID = Convert.ToInt64(dTblResultSeg.Rows[0]["ViewID"]);
            }

            if (lngViewID > 0 && vm.OutboundCampaign != null)
            {
                vm.OutboundCampaign.ViewID = Convert.ToInt32(lngViewID);

                DataTable dTblResultCam = new DataTable();

                if (vm.IsHCLEmailBlast == true)
                    dTblResultCam = repo.UpdateEmailBlastCampaign(vm.OutboundCampaign, strLastUpdatedBy, dtLastUpdatedDateTime);
                else
                    dTblResultCam = repo.UpdateOutboundCampaign(vm.OutboundCampaign, strLastUpdatedBy, dtLastUpdatedDateTime);

                if (dTblResultCam != null && dTblResultCam.Rows.Count > 0)
                {
                    intCampaignID = Convert.ToInt32(dTblResultCam.Rows[0]["CampaignID"]);
                }
            }

            if (lngViewID > 0 && vm.AdvancedRules != null && vm.AdvancedRules.PermissionUsers != null)
            {
                repoGeneral.UpdatePermissionUser(vm.IsHCLEmailBlast == true ? 6 : (int)Constant.TableType.Outbound, vm.AdvancedRules.PermissionUsers, Convert.ToInt32(lngViewID));
            }

            if (lngViewID > 0 && vm.AdvancedRules != null && vm.AdvancedRules.PermissionRoles != null)
            {
                repoGeneral.UpdatePermissionRole(vm.IsHCLEmailBlast == true ? 6 : (int)Constant.TableType.Outbound, vm.AdvancedRules.PermissionRoles, Convert.ToInt32(lngViewID));
            }


            return lst;

        }


        public List<ChangeHistoryUpdateViewModel> InsertChangeHistory(List<ChangeHistoryUpdateViewModel> model, string strUserName, string strUserID, DateTime dtUpdated)
        {
            int intReturnValue = 0;
            List<ChangeHistoryUpdateViewModel> lst = model.Where(x => x.IsChanged).ToList();
            intReturnValue = repo.InsertChangeHistory(lst, strUserName, strUserID, dtUpdated);

            return lst;
        }

        public List<SegmentiseListingViewModel> GetAllSegmentiseList(SegmentisePagedListViewModel paging, out int intCount)
        {
            intCount = 0;
            DataSet ds = repo.GetAllSegmentiseList(paging);

            List<SegmentiseListingViewModel> lstSegmentizeVM = new List<SegmentiseListingViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstSegmentizeVM = repo.DataTableToList<SegmentiseListingViewModel>(ds.Tables[0]).ToList();

                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstSegmentizeVM;
        }

        public List<SegmentiseListingViewModel> GetAllEmailBlastSegmentiseList(SegmentisePagedListViewModel paging, out int intCount)
        {
            intCount = 0;
            DataSet ds = repo.GetAllEmailBlastSegmentiseList(paging);

            List<SegmentiseListingViewModel> lstSegmentizeVM = new List<SegmentiseListingViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstSegmentizeVM = repo.DataTableToList<SegmentiseListingViewModel>(ds.Tables[0]).ToList();

                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstSegmentizeVM;
        }

        public List<ReMSBatchListingViewModel> GetAllReMSBatchList(ReMSBatchPagedListViewModel paging, out int intCount)
        {
            intCount = 0;
            DataSet ds = repo.GetAllReMSBatchList(paging);

            List<ReMSBatchListingViewModel> lstVM = new List<ReMSBatchListingViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstVM = repo.DataTableToList<ReMSBatchListingViewModel>(ds.Tables[0]).ToList();

                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstVM;
        }

        public List<HCLEmailBlastBatchListingViewModel> GetAllEmailBlastBatchList(HCLEmailBlastBatchPagedListViewModel paging, out int intCount)
        {
            intCount = 0;
            DataSet ds = repo.GetAllEmailBlastBatchList(paging);

            List<HCLEmailBlastBatchListingViewModel> lstVM = new List<HCLEmailBlastBatchListingViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstVM = repo.DataTableToList<HCLEmailBlastBatchListingViewModel>(ds.Tables[0]).ToList();

                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstVM;
        }

        public List<ReMSDataListingViewModel> GetReMSDataByBatchID(ReMSDataPagedListViewModel paging, out int intCount)
        {
            intCount = 0;
            DataSet ds = repo.GetReMSDataByBatchID(paging);

            List<ReMSDataListingViewModel> lstVM = new List<ReMSDataListingViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstVM = repo.DataTableToList<ReMSDataListingViewModel>(ds.Tables[0]).ToList();

                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstVM;
        }

        public List<HCLEmailBlastDataListingViewModel> GetHCLEmailBlastDataByBatchID(HCLEmailBlastDataPagedListViewModel paging, out int intCount)
        {
            intCount = 0;
            DataSet ds = repo.GetHCLEmailBlastDataByBatchID(paging);

            List<HCLEmailBlastDataListingViewModel> lstVM = new List<HCLEmailBlastDataListingViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstVM = repo.DataTableToList<HCLEmailBlastDataListingViewModel>(ds.Tables[0]).ToList();

                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstVM;
        }

        public List<ReMSDataListingViewModel> GetInvalidReMSDataByBatchID(ReMSDataPagedListViewModel paging, out int intCount)
        {
            intCount = 0;
            DataSet ds = repo.GetInvalidReMSDataByBatchID(paging);

            List<ReMSDataListingViewModel> lstVM = new List<ReMSDataListingViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstVM = repo.DataTableToList<ReMSDataListingViewModel>(ds.Tables[0]).ToList();

                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstVM;
        }

        public List<HCLEmailBlastDataListingViewModel> GetInvalidEmailBlastDataByBatchID(HCLEmailBlastDataPagedListViewModel paging, out int intCount)
        {
            intCount = 0;
            DataSet ds = repo.GetInvalidEmailBlastDataByBatchID(paging);

            List<HCLEmailBlastDataListingViewModel> lstVM = new List<HCLEmailBlastDataListingViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstVM = repo.DataTableToList<HCLEmailBlastDataListingViewModel>(ds.Tables[0]).ToList();

                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstVM;
        }

        public ReMSBatchListingViewModel GetReMSBatchDetailsByBatchID(int intBatchID, int intJenisKempenID)
        {
            ReMSBatchListingViewModel model = repo.GetReMSBatchDetailsByBatchID(intBatchID, intJenisKempenID);
            model.ReturnedReasonOptions = Utilities.SortDDL(AdminService.LookupParams.Where(x => x.LookupCode == "ReturnedReason" && x.IsActive == true).Select(x => new DropdownDetailViewModel { Value = x.LookupParamID, Text = x.ParamDesc, IsDefault = x.IsDefault, Code = x.LookupValue, SeqNo = x.SeqNo }).ToList());
            model.KodSelesaiDesc = AdminService.KodSelesai.Where(x => x.KodSelesaiID == 31).ToList().FirstOrDefault()?.KodSelesaiDesc;

            return model;
        }

        public HCLEmailBlastBatchListingViewModel GetEmailBlastBatchDetailsByBatchID(int intBatchID, int intJenisKempenID)
        {
            return repo.GetEmailBlastBatchDetailsByBatchID(intBatchID, intJenisKempenID);
        }

        public bool ReturnReMSBatch(ReMSBatchReturnViewModel model, out int intNoOfRecord)
        {
            bool blnIsSuccess = false;
            //update ReMSBatch
            //repo.ReturnReMSBatch(model);

            //update ReMS
            intNoOfRecord = repo.ReturnReMSByBatchID(model);
            blnIsSuccess = true;

            return blnIsSuccess;
        }

        public int RejectEmailBlastBatch(HCLEmailBlastDataPagedListViewModel model, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            DataSet ds = repo.RejectEmailBlastByBatchID(model, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
            List<HCLEmailBlastUpdateViewModel> lstReject = new List<HCLEmailBlastUpdateViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstReject = repo.DataTableToList<HCLEmailBlastUpdateViewModel>(ds.Tables[0]).ToList();
            }

            if (lstReject != null)
            {
                int i = 0;
                List<ChangeHistoryUpdateViewModel> lstChgHistory = new List<ChangeHistoryUpdateViewModel>();
                string strNewStatus = Utilities.GetEnumDescription(Constant.OutboundStatus.DitolakDipulangkan);

                for (i = 0; i < lstReject.Count; i++)
                {
                    string strOldStatus = Utilities.GetEnumDescription((Constant.OutboundStatus)lstReject[i].EmailBlastStatusID);
                    lstChgHistory.Add(BindChangeHistVM(lstReject[i].EmailDataID, "EmailBlastStatusID", "Status", strOldStatus, strNewStatus, model.JenisKempenID));
                }

                if (lstChgHistory != null)
                {
                    repo.InsertEmailBlastChangeHistory(lstChgHistory, strLastUpdatedByName, strLastUpdatedBy, dtLastUpdatedDateTime);
                }
            }
            return lstReject.Count;
        }

        public bool DeleteSegmentise(OutboundSegmentiseViewModel model)
        {
            byte[] oriChangeStamp = repo.GetChangeStampbyID(model.ViewID, (int)Constant.TableType.Outbound_View);
            bool blnIsSuccess = false;
            if (!Utilities.CompareByteArray(model.ChangeStamp, oriChangeStamp))
            {
                //TODO Update conflict
                throw new UpdateConflictException();
            }
            blnIsSuccess = repo.DeleteSegmentise(model.ViewID);

            return blnIsSuccess;
        }

        public bool DeleteEmailBlastSegmentise(OutboundSegmentiseViewModel model)
        {
            byte[] oriChangeStamp = repo.GetChangeStampbyID(model.ViewID, (int)Constant.TableType.HCL_EmailView);
            bool blnIsSuccess = false;
            if (!Utilities.CompareByteArray(model.ChangeStamp, oriChangeStamp))
            {
                //TODO Update conflict
                throw new UpdateConflictException();
            }
            blnIsSuccess = repo.DeleteEmailBlastSegmentise(model.ViewID);

            return blnIsSuccess;
        }

        public bool DeleteCampaign(OutboundCampaignViewModel model)
        {
            byte[] oriChangeStamp = repo.GetChangeStampbyID(model.ViewID, (int)Constant.TableType.Outbound_Campaign);
            bool blnIsSuccess = false;
            if (!Utilities.CompareByteArray(model.ChangeStamp, oriChangeStamp))
            {
                //TODO Update conflict
                throw new UpdateConflictException();
            }
            blnIsSuccess = repo.DeleteCampaign(model.ViewID);

            return blnIsSuccess;
        }

        public bool DeleteEmailBlastCampaign(OutboundCampaignViewModel model)
        {
            byte[] oriChangeStamp = repo.GetChangeStampbyID(model.ViewID, (int)Constant.TableType.HCL_EmailCampaign);
            bool blnIsSuccess = false;
            if (!Utilities.CompareByteArray(model.ChangeStamp, oriChangeStamp))
            {
                //TODO Update conflict
                throw new UpdateConflictException();
            }
            blnIsSuccess = repo.DeleteEmailBlastCampaign(model.ViewID);

            return blnIsSuccess;
        }

        public List<OutboundScheduleViewModel> GetAllOutboundSchedule(OutboundSchedulePagedListViewModel paging, out int intCount)
        {
            intCount = 0;

            DataSet ds = repo.GetAllOutboundSchedule(paging.SortExpression, paging.PageIndex, paging.Length,
                                            paging.CampaignID);

            List<OutboundScheduleViewModel> lstOutScheduleVM = new List<OutboundScheduleViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstOutScheduleVM = repo.DataTableToList<OutboundScheduleViewModel>(ds.Tables[0]).ToList();
                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstOutScheduleVM;
        }

        public List<OutboundScheduleViewModel> GetAllEmailBlastSchedule(OutboundSchedulePagedListViewModel paging, out int intCount)
        {
            intCount = 0;

            DataSet ds = repo.GetAllEmailBlastSchedule(paging.SortExpression, paging.PageIndex, paging.Length,
                                            paging.CampaignID);

            List<OutboundScheduleViewModel> lstOutScheduleVM = new List<OutboundScheduleViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstOutScheduleVM = repo.DataTableToList<OutboundScheduleViewModel>(ds.Tables[0]).ToList();
                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstOutScheduleVM;
        }

        public OutboundScheduleViewModel GetOutboundScheduleByID(int intScheduleID)
        {
            OutboundScheduleViewModel vm = null;

            vm = repo.GetOutboundScheduleByID(intScheduleID);


            return vm;
        }

        public OutboundScheduleViewModel GetEmailBlastScheduleByID(int intScheduleID)
        {
            OutboundScheduleViewModel vm = null;

            vm = repo.GetEmailBlastScheduleByID(intScheduleID);


            return vm;
        }

        public OutboundScheduleViewModel UpdateOutboundSchedule(OutboundScheduleUpdateViewModel vm, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime,
                                                                out int intScheduleID,
                                                                out DateTime dtScheduleStartDate,
                                                                out DateTime dtScheduleExpiryDate)
        {
            OutboundScheduleViewModel lst = new OutboundScheduleViewModel();
            intScheduleID = 0;
            dtScheduleStartDate = new DateTime();
            dtScheduleExpiryDate = new DateTime();


            //Part 1: Insert Outbound Schedule
            DataTable dTblResultSchedule = new DataTable();
            if (vm.IsHCLEmailBlast == true)
            {
                dTblResultSchedule = repo.UpdateEmailBlastScheduleByID(vm.OutboundSchedule, strLastUpdatedBy, dtLastUpdatedDateTime);
            }
            else
            {
                dTblResultSchedule = repo.UpdateOutboundScheduleByID(vm.OutboundSchedule, strLastUpdatedBy, dtLastUpdatedDateTime);
            }

            if (dTblResultSchedule != null && dTblResultSchedule.Rows.Count > 0)
            {
                intScheduleID = Convert.ToInt32(dTblResultSchedule.Rows[0]["ScheduleID"]);
                dtScheduleStartDate = Convert.ToDateTime(dTblResultSchedule.Rows[0]["ScheduleStartDate"]);
                dtScheduleExpiryDate = Convert.ToDateTime(dTblResultSchedule.Rows[0]["ScheduleExpiryDate"]);
            }

            //Part 2: Get Outbound Result 
            DataSet ds = new DataSet();
            if (vm.IsHCLEmailBlast == true)
            {
                ds = repo.GetSearchEmailBlastResult(vm.OutboundFilter);
            }
            else
            {
                ds = repo.GetSearchOutboundResult(vm.OutboundFilter);
            }

            dynamic lstresult = null;

            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstresult = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(ds.Tables[0]));

                //Part 3: Insert Dynamic Result to List
                List<OutboundUpdateViewModel> lstInsertOutbound = new List<OutboundUpdateViewModel>();
                List<HCLEmailBlastUpdateViewModel> lstInsertEmailBlast = new List<HCLEmailBlastUpdateViewModel>();

                JArray arrResult = JArray.Parse(lstresult.ToString());
                int i = 0;
                if (vm.IsHCLEmailBlast == true)
                {
                    for (i = 0; i < arrResult.Count; i++)
                    {
                        HCLEmailBlastUpdateViewModel insertEmailBlast = new HCLEmailBlastUpdateViewModel();

                        insertEmailBlast.JenisKempenId = (int)arrResult[i]["JenisKempenID"]; //Convert.ToInt32(item.JenisKempenID.ToString());
                        insertEmailBlast.EmailDataID = (long)arrResult[i]["EmailDataID"];
                        insertEmailBlast.EmailBlastStatusID = (int)arrResult[i]["EmailBlastStatusID"];
                        insertEmailBlast.ScheduleID = intScheduleID;
                        insertEmailBlast.CampaignID = vm.OutboundSchedule.CampaignID;
                        //insertEmailBlast.StatusID = (int)Constant.OutboundStatus.Dijadualkan;
                        insertEmailBlast.Kategori1ID = vm.OutboundCampaign.Kategori1ID;
                        insertEmailBlast.Kategori2ID = vm.OutboundCampaign.Kategori2ID;
                        insertEmailBlast.Kategori3ID = vm.OutboundCampaign.Kategori3ID;
                        insertEmailBlast.EmailTemplateID = vm.OutboundCampaign.EmailTemplateID;
                        //insertEmailBlast.ScheduledDateTime = model.OutboundSchedule.ScheduleStartDate; //ToCheck
                        //insertEmailBlast.RunDate = model.OutboundSchedule.ScheduleStartDate; //ToCheck

                        lstInsertEmailBlast.Add(insertEmailBlast);
                    }

                    //Part 4: get data with status = New, change to scheduled after filter and insert to outbound table
                    if (vm.IsRequireVerification == true)
                        lstInsertEmailBlast = lstInsertEmailBlast.Where(x => x.EmailBlastStatusID == (int)Constant.OutboundStatus.Disahkan).Select(x => { x.EmailBlastStatusID = (int)Constant.OutboundStatus.Dijadualkan; return x; }).ToList();
                    else
                        lstInsertEmailBlast = lstInsertEmailBlast.Where(x => x.EmailBlastStatusID == (int)Constant.OutboundStatus.Baru || x.EmailBlastStatusID == (int)Constant.OutboundStatus.Disahkan).Select(x => { x.EmailBlastStatusID = (int)Constant.OutboundStatus.Dijadualkan; return x; }).ToList();

                    if (lstInsertEmailBlast.Count > 0)
                    {
                        repo.InsertEmailBlastByList(lstInsertEmailBlast, strLastUpdatedBy, dtLastUpdatedDateTime);

                        //Part 5: Update email data
                        List<HCLEmailBlastUpdateViewModel> objdatalist = lstInsertEmailBlast.Select(x => new HCLEmailBlastUpdateViewModel
                        {
                            EmailDataID = x.EmailDataID
                        }).ToList();

                        repo.UpdateEmailBlastEmailDataStatus(objdatalist, (int)Constant.OutboundStatus.Dijadualkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime, blnUpdateProfile: false);

                    }
                }
                else
                {
                    for (i = 0; i < arrResult.Count; i++)
                    {
                        OutboundUpdateViewModel insertOutbound = new OutboundUpdateViewModel();

                        insertOutbound.JenisKempenId = (int)arrResult[i]["JenisKempenID"]; //Convert.ToInt32(item.JenisKempenID.ToString()); 
                        insertOutbound.ReMSDataID = (long)arrResult[i]["DataID"];
                        insertOutbound.StatusID = (int)arrResult[i]["StatusID"];
                        insertOutbound.ScheduleID = intScheduleID;
                        insertOutbound.CampaignID = vm.OutboundSchedule.CampaignID;
                        //insertOutbound.StatusID = (int)Constant.OutboundStatus.Dijadualkan;
                        insertOutbound.Kategori1ID = vm.OutboundCampaign.Kategori1ID;
                        insertOutbound.Kategori2ID = vm.OutboundCampaign.Kategori2ID;
                        insertOutbound.Kategori3ID = vm.OutboundCampaign.Kategori3ID;
                        insertOutbound.EmailTemplateID = vm.OutboundCampaign.EmailTemplateID;
                        //insertOutbound.ScheduledDateTime = model.OutboundSchedule.ScheduleStartDate; //ToCheck
                        //insertOutbound.RunDate = model.OutboundSchedule.ScheduleStartDate; //ToCheck
                        //insertOutbound.ScheduledStartDate = dtScheduleStartDate;
                        //insertOutbound.ScheduledExpiryDate = dtScheduleExpiryDate;

                        lstInsertOutbound.Add(insertOutbound);
                    }

                    //Part 4: get data with status = New, change to scheduled after filter and insert to outbound table
                    if (vm.IsRequireVerification == true)
                        lstInsertOutbound = lstInsertOutbound.Where(x => x.StatusID == (int)Constant.OutboundStatus.Disahkan).Select(x => { x.StatusID = (int)Constant.OutboundStatus.Dijadualkan; return x; }).ToList();
                    else
                        lstInsertOutbound = lstInsertOutbound.Where(x => x.StatusID == (int)Constant.OutboundStatus.Baru || x.StatusID == (int)Constant.OutboundStatus.Disahkan).Select(x => { x.StatusID = (int)Constant.OutboundStatus.Dijadualkan; return x; }).ToList();

                    if (lstInsertOutbound.Count > 0)
                    {
                        repo.InsertOutboundByList(lstInsertOutbound, strLastUpdatedBy, dtLastUpdatedDateTime);

                        //Part 5: Update rems data
                        JenisKempenDetailViewModel objJenisKempenDetails = repo.GetJenisKempenDetailByID((int)lstInsertOutbound[0].JenisKempenId, 0);
                        var ReMSTableName = objJenisKempenDetails.ReMSTableName;

                        List<OutboundUpdateViewModel> objdatalist = lstInsertOutbound.Select(x => new OutboundUpdateViewModel
                        {
                            ReMSDataID = x.ReMSDataID
                        }).ToList();


                        repo.UpdateOutboundReMSStatus(objdatalist, ReMSTableName, (int)Constant.OutboundStatus.Dijadualkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime, blnUpdateProfile: false);

                    }
                }
            }
            return lst;

        }

        public bool DeleteSchedule(OutboundScheduleViewModel model, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            OutboundScheduleViewModel vm = null;
            vm = GetOutboundScheduleByID(model.ScheduleID);
            bool blnIsRun = vm.HasRun.HasValue ? vm.HasRun.Value : false;
            bool blnValid = true;
            if (blnIsRun || vm.ScheduleStartDate < DateTime.Now || vm.OutboundScheduleID > 0)
            {
                blnValid = false;
            }

            if (blnValid)
            {
                byte[] oriChangeStamp = repo.GetChangeStampbyID(model.ScheduleID, (int)Constant.TableType.Outbound_Schedule);
                bool blnIsSuccess = false;
                if (!Utilities.CompareByteArray(model.ChangeStamp, oriChangeStamp))
                {
                    //TODO Update conflict
                    throw new UpdateConflictException();
                }
                JenisKempenDetailViewModel objJenisKempenDetails = repo.GetJenisKempenDetailByID(model.JenisKempenID, 0);
                var ReMSTableName = objJenisKempenDetails.ReMSTableName;

                blnIsSuccess = repo.DeleteSchedule(model.ScheduleID, ReMSTableName, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);

                return blnIsSuccess;
            }
            else
            {
                return blnValid;
            }
        }

        public bool DeleteEmailBlastSchedule(OutboundScheduleViewModel model, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            OutboundScheduleViewModel vm = null;
            vm = GetEmailBlastScheduleByID(model.ScheduleID);
            bool blnIsRun = vm.HasRun.HasValue ? vm.HasRun.Value : false;
            bool blnValid = true;
            if (blnIsRun || vm.ScheduleStartDate < DateTime.Now || vm.OutboundScheduleID > 0)
            {
                blnValid = false;
            }

            if (blnValid)
            {
                byte[] oriChangeStamp = repo.GetChangeStampbyID(model.ScheduleID, (int)Constant.TableType.HCL_EmailSchedule);
                bool blnIsSuccess = false;
                if (!Utilities.CompareByteArray(model.ChangeStamp, oriChangeStamp))
                {
                    //TODO Update conflict
                    throw new UpdateConflictException();
                }

                blnIsSuccess = repo.DeleteEmailBlastSchedule(model.ScheduleID, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);

                return blnIsSuccess;
            }
            else
            {
                return false;
            }
        }

        public List<OutboundHistoryViewModel> GetOutboundHistoryListByID(OutboundHistoryPagedListViewModel paging, out int intCount)
        {
            intCount = 0;

            DataSet ds = repo.GetOutboundHistoryListByID(paging.SortExpression, paging.PageIndex, paging.Length,
                                            paging.CampaignID);

            List<OutboundHistoryViewModel> lstOutHisVM = new List<OutboundHistoryViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstOutHisVM = repo.DataTableToList<OutboundHistoryViewModel>(ds.Tables[0]).ToList();
                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstOutHisVM;


        }

        public List<HCLEmailBlastHistoryViewModel> GetEmailBlastHistoryListByID(OutboundHistoryPagedListViewModel paging, out int intCount)
        {
            intCount = 0;

            DataSet ds = repo.GetEmailBlastHistoryListByID(paging.SortExpression, paging.PageIndex, paging.Length,
                                            paging.CampaignID);

            List<HCLEmailBlastHistoryViewModel> lstOutHisVM = new List<HCLEmailBlastHistoryViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstOutHisVM = repo.DataTableToList<HCLEmailBlastHistoryViewModel>(ds.Tables[0]).ToList();
                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstOutHisVM;

        }

        public OutboundHistoryViewModel GetOutboundHistoryByID(long lngOutboundHistID)
        {
            OutboundHistoryViewModel vm = null;

            vm = repo.GetOutboundHistoryByID(lngOutboundHistID);


            return vm;
        }

        public HCLEmailBlastHistoryViewModel GetEmailBlastHistoryByID(long lngEmailHistID)
        {
            HCLEmailBlastHistoryViewModel vm = null;

            vm = repo.GetEmailBlastHistoryByID(lngEmailHistID);


            return vm;
        }

        public List<OutboundHistoryDetailViewModel> GetOutboundHistoryDetailListByID(OutboundHistoryDetailPagedListViewModel paging, out int intCount)
        {
            intCount = 0;

            DataSet ds = repo.GetOutboundHistoryDetailListByID(paging.SortExpression, paging.PageIndex, paging.Length,
                                            paging.OutboundHistID);

            List<OutboundHistoryDetailViewModel> lstOutHisDVM = new List<OutboundHistoryDetailViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstOutHisDVM = repo.DataTableToList<OutboundHistoryDetailViewModel>(ds.Tables[0]).ToList();
                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstOutHisDVM;
        }

        public List<HCLEmailBlastHistoryDetailViewModel> GetEmailBlastHistoryDetailListByID(OutboundHistoryDetailPagedListViewModel paging, out int intCount)
        {
            intCount = 0;

            DataSet ds = repo.GetEmailBlastHistoryDetailListByID(paging.SortExpression, paging.PageIndex, paging.Length,
                                            paging.OutboundHistID);

            List<HCLEmailBlastHistoryDetailViewModel> lstOutHisDVM = new List<HCLEmailBlastHistoryDetailViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstOutHisDVM = repo.DataTableToList<HCLEmailBlastHistoryDetailViewModel>(ds.Tables[0]).ToList();
                if (ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                    intCount = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
            }

            return lstOutHisDVM;
        }

        public long AddOutboundSyncSchedule(long scheduleID, DateTime startDate, DateTime endDate)
        {
            return repo.AddOutboundSyncSchedule(scheduleID, startDate, endDate);
        }

        public void AddOutboundSSISTask(long scheduleID, long viewID, string userID, DateTime startDate, DateTime endDate, bool blnIsHCLEmailBlast)
        {
            repo.AddOutboundSSISTask(scheduleID, viewID, userID, startDate, endDate, blnIsHCLEmailBlast);
        }

        public string InsertEmailBlastBatch(HCLEmailBlastUploadParamViewModel model, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            DataSet ds = new DataSet();
            string strBatchRefNo = string.Empty;

            ds = repo.InsertEmailBlastBatch(model, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                {
                    strBatchRefNo = ds.Tables[0].Rows[0][0].ToString();
                }
            }
            return strBatchRefNo;
        }

        public long LockSegmentiseData(OutboundScheduleUpdateViewModel vm, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            //Part 1: Get Outbound Result 
            DataSet ds = new DataSet();
            if (vm.IsHCLEmailBlast == true)
                ds = repo.GetSearchEmailBlastResult(vm.OutboundFilter);
            else
                ds = repo.GetSearchOutboundResult(vm.OutboundFilter);

            dynamic lstresult = null;
            JArray arrResult = null;
            List<OutboundUpdateViewModel> lstInsertOutbound = new List<OutboundUpdateViewModel>();
            List<HCLEmailBlastUpdateViewModel> lstInsertEmailBlast = new List<HCLEmailBlastUpdateViewModel>();

            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstresult = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(ds.Tables[0]));

                //Part 2: Insert Dynamic Result to List
                arrResult = JArray.Parse(lstresult.ToString());
                int i = 0;
                if (vm.IsHCLEmailBlast == true)
                {
                    for (i = 0; i < arrResult.Count; i++)
                    {
                        HCLEmailBlastUpdateViewModel insertEmailBlast = new HCLEmailBlastUpdateViewModel();

                        insertEmailBlast.JenisKempenId = (int)arrResult[i]["JenisKempenID"]; //Convert.ToInt32(item.JenisKempenID.ToString());
                        insertEmailBlast.EmailDataID = (long)arrResult[i]["EmailDataID"];
                        insertEmailBlast.EmailBlastStatusID = (int)arrResult[i]["EmailBlastStatusID"];
                        insertEmailBlast.CampaignID = vm.OutboundCampaign.CampaignID;
                        insertEmailBlast.Kategori1ID = vm.OutboundCampaign.Kategori1ID;
                        insertEmailBlast.Kategori2ID = vm.OutboundCampaign.Kategori2ID;
                        insertEmailBlast.Kategori3ID = vm.OutboundCampaign.Kategori3ID;
                        insertEmailBlast.EmailTemplateID = vm.OutboundCampaign.EmailTemplateID;

                        lstInsertEmailBlast.Add(insertEmailBlast);
                    }

                    //Part 3: get data with status = New, change to scheduled after filter and insert to outbound table
                    if (vm.IsRequireVerification == true)
                        lstInsertEmailBlast = lstInsertEmailBlast.Where(x => x.EmailBlastStatusID == (int)Constant.OutboundStatus.Disahkan).Select(x => { x.EmailBlastStatusID = (int)Constant.OutboundStatus.Dijadualkan; return x; }).ToList();
                    else
                        lstInsertEmailBlast = lstInsertEmailBlast.Where(x => x.EmailBlastStatusID == (int)Constant.OutboundStatus.Baru || x.EmailBlastStatusID == (int)Constant.OutboundStatus.Disahkan).Select(x => { x.EmailBlastStatusID = (int)Constant.OutboundStatus.Dijadualkan; return x; }).ToList();

                    if (lstInsertEmailBlast.Count > 0)
                    {
                        repo.LockEmailBlastSegmentiseData(lstInsertEmailBlast, strLastUpdatedBy, dtLastUpdatedDateTime);

                        //Part 4: Update email data
                        List<HCLEmailBlastUpdateViewModel> objdatalist = lstInsertEmailBlast.Select(x => new HCLEmailBlastUpdateViewModel
                        {
                            EmailDataID = x.EmailDataID
                        }).ToList();

                        repo.UpdateEmailBlastEmailDataStatus(objdatalist, (int)Constant.OutboundStatus.Dijadualkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime, blnUpdateProfile: false);
                    }
                }
                else
                {
                    for (i = 0; i < arrResult.Count; i++)
                    {
                        OutboundUpdateViewModel insertOutbound = new OutboundUpdateViewModel();

                        insertOutbound.JenisKempenId = (int)arrResult[i]["JenisKempenID"]; //Convert.ToInt32(item.JenisKempenID.ToString()); 
                        insertOutbound.ReMSDataID = (long)arrResult[i]["DataID"];
                        insertOutbound.StatusID = (int)arrResult[i]["StatusID"];
                        insertOutbound.CampaignID = vm.OutboundCampaign.CampaignID;
                        insertOutbound.Kategori1ID = vm.OutboundCampaign.Kategori1ID;
                        insertOutbound.Kategori2ID = vm.OutboundCampaign.Kategori2ID;
                        insertOutbound.Kategori3ID = vm.OutboundCampaign.Kategori3ID;
                        insertOutbound.EmailTemplateID = vm.OutboundCampaign.EmailTemplateID;

                        lstInsertOutbound.Add(insertOutbound);
                    }

                    //Part 3: get data with status = New, change to scheduled after filter and insert to outbound table
                    if (vm.IsRequireVerification == true)
                        lstInsertOutbound = lstInsertOutbound.Where(x => x.StatusID == (int)Constant.OutboundStatus.Disahkan).Select(x => { x.StatusID = (int)Constant.OutboundStatus.Dijadualkan; return x; }).ToList();
                    else
                        lstInsertOutbound = lstInsertOutbound.Where(x => x.StatusID == (int)Constant.OutboundStatus.Baru || x.StatusID == (int)Constant.OutboundStatus.Disahkan).Select(x => { x.StatusID = (int)Constant.OutboundStatus.Dijadualkan; return x; }).ToList();

                    if (lstInsertOutbound.Count > 0)
                    {
                        repo.LockOutboundSegmentiseData(lstInsertOutbound, strLastUpdatedBy, dtLastUpdatedDateTime);

                        //Part 4: Update rems data
                        JenisKempenDetailViewModel objJenisKempenDetails = repo.GetJenisKempenDetailByID((int)lstInsertOutbound[0].JenisKempenId, 0);
                        var ReMSTableName = objJenisKempenDetails.ReMSTableName;

                        List<OutboundUpdateViewModel> objdatalist = lstInsertOutbound.Select(x => new OutboundUpdateViewModel
                        {
                            ReMSDataID = x.ReMSDataID
                        }).ToList();


                        repo.UpdateOutboundReMSStatus(objdatalist, ReMSTableName, (int)Constant.OutboundStatus.Dijadualkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime, blnUpdateProfile: false);
                    }
                }
            }

            if (vm.IsHCLEmailBlast == true)
                return lstInsertEmailBlast.Count;
            else
                return lstInsertOutbound.Count;
        }

        public long ReleaseSegmentiseData(OutboundScheduleUpdateViewModel vm, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            //Part 1: Get Outbound Result 
            DataSet ds = new DataSet();
            if (vm.IsHCLEmailBlast == true)
                ds = repo.GetSearchEmailBlastResult(vm.OutboundFilter);
            else
                ds = repo.GetSearchOutboundResult(vm.OutboundFilter);

            dynamic lstresult = null;
            JArray arrResult = null;
            List<OutboundUpdateViewModel> lstReleaseOutbound = new List<OutboundUpdateViewModel>();
            List<HCLEmailBlastUpdateViewModel> lstReleaseEmailBlast = new List<HCLEmailBlastUpdateViewModel>();

            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                    lstresult = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(ds.Tables[0]));

                //Part 2: Insert Dynamic Result to List
                arrResult = JArray.Parse(lstresult.ToString());
                int i = 0;
                if (vm.IsHCLEmailBlast == true)
                {
                    for (i = 0; i < arrResult.Count; i++)
                    {
                        HCLEmailBlastUpdateViewModel insertEmailBlast = new HCLEmailBlastUpdateViewModel();

                        insertEmailBlast.JenisKempenId = (int)arrResult[i]["JenisKempenID"]; //Convert.ToInt32(item.JenisKempenID.ToString());
                        insertEmailBlast.EmailDataID = (long)arrResult[i]["EmailDataID"];
                        insertEmailBlast.EmailBlastStatusID = (int)arrResult[i]["EmailBlastStatusID"];
                        insertEmailBlast.CampaignID = vm.OutboundCampaign.CampaignID;

                        lstReleaseEmailBlast.Add(insertEmailBlast);
                    }

                    //Part 3: get data with status = Scheduled and delete from outbound table
                    lstReleaseEmailBlast = lstReleaseEmailBlast.Where(x => x.EmailBlastStatusID == (int)Constant.OutboundStatus.Dijadualkan).ToList();

                    if (lstReleaseEmailBlast.Count > 0)
                    {
                        repo.ReleaseEmailBlastSegmentiseData(lstReleaseEmailBlast, strLastUpdatedBy, dtLastUpdatedDateTime);

                        //Part 4: Update email data
                        List<HCLEmailBlastUpdateViewModel> objdatalist = lstReleaseEmailBlast.Select(x => new HCLEmailBlastUpdateViewModel
                        {
                            EmailDataID = x.EmailDataID
                        }).ToList();

                        repo.UpdateEmailBlastEmailDataStatus(objdatalist, (int)Constant.OutboundStatus.Disahkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime, blnUpdateProfile: false);
                    }
                }
                else
                {
                    for (i = 0; i < arrResult.Count; i++)
                    {
                        OutboundUpdateViewModel insertOutbound = new OutboundUpdateViewModel();

                        insertOutbound.JenisKempenId = (int)arrResult[i]["JenisKempenID"]; //Convert.ToInt32(item.JenisKempenID.ToString()); 
                        insertOutbound.ReMSDataID = (long)arrResult[i]["DataID"];
                        insertOutbound.StatusID = (int)arrResult[i]["StatusID"];
                        insertOutbound.CampaignID = vm.OutboundCampaign.CampaignID;

                        lstReleaseOutbound.Add(insertOutbound);
                    }

                    //Part 3: get data with status = Sceduled, change to verified after filter and delete from outbound table
                    lstReleaseOutbound = lstReleaseOutbound.Where(x => x.StatusID == (int)Constant.OutboundStatus.Dijadualkan).ToList();

                    if (lstReleaseOutbound.Count > 0)
                    {
                        repo.ReleaseOutboundSegmentiseData(lstReleaseOutbound, strLastUpdatedBy, dtLastUpdatedDateTime);

                        //Part 4: Update rems data
                        JenisKempenDetailViewModel objJenisKempenDetails = repo.GetJenisKempenDetailByID((int)lstReleaseOutbound[0].JenisKempenId, 0);
                        var ReMSTableName = objJenisKempenDetails.ReMSTableName;

                        List<OutboundUpdateViewModel> objdatalist = lstReleaseOutbound.Select(x => new OutboundUpdateViewModel
                        {
                            ReMSDataID = x.ReMSDataID
                        }).ToList();


                        repo.UpdateOutboundReMSStatus(objdatalist, ReMSTableName, (int)Constant.OutboundStatus.Disahkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime, blnUpdateProfile: false);
                    }
                }
            }

            if (vm.IsHCLEmailBlast == true)
                return lstReleaseEmailBlast.Count;
            else
                return lstReleaseOutbound.Count;
        }

        public HCLEmailBlastDetailsViewModel GetEmailBlastDetails(OutboundParamViewModel vm)
        {
            if (vm.DataID == 0 || vm.JenisKempenID == 0)
            {
                throw new NotFoundException("Jenis Kempen ID or Email Data ID is invalid!");
            }

            HCLEmailBlastDetailsViewModel obj = null;
            obj = repo.GetEmailBlastDetails((int)vm.JenisKempenID, (long)vm.DataID);

            if (obj == null)
            {
                throw new NotFoundException("Email Blast details not found!");
            }

            return obj;
        }

        public List<ChangeHistoryUpdateViewModel> UpdateHCLEmailBlastDetails(HCLEmailBlastDetailsUpdateViewModel vm)
        {
            List<ChangeHistoryUpdateViewModel> lst = new List<ChangeHistoryUpdateViewModel>();

            string emailblastNewStatus = string.Empty;

            // Retrieve orginal records for audit and change history 
            OutboundParamViewModel model = new OutboundParamViewModel();
            model.DataID = vm.EmailBlastDetails.EmailDataID;
            model.JenisKempenID = vm.EmailBlastDetails.JenisKempenID;

            HCLEmailBlastDetailsViewModel oriHCLEmailBlastDetails = GetEmailBlastDetails(model);
            // 1. Check for update conflict
            if (!Utilities.CompareByteArray(vm.EmailBlastDetails.ChangeStamp, oriHCLEmailBlastDetails.ChangeStamp))
            {
                throw new UpdateConflictException();
            }

            int i = repo.UpdateEmailBlastDetailsHCL(vm.EmailBlastDetails);

            // 3.Get ChangeHistory
            foreach (ChangeHistoryUpdateViewModel changeHistoryItem in vm.ChangeHistory)
            {
                //Get object original value
                string strOriValue = string.Empty;

                var obj = Utilities.GetPropertyValue(oriHCLEmailBlastDetails, changeHistoryItem.FieldName);
                if (obj != null)
                {
                    switch (obj.GetType().Name)
                    {
                        case "DateTime":
                            strOriValue = Convert.ToDateTime(obj).ToString("dd MMM yyyy");
                            break;
                        case "Boolean":
                            bool flag = (bool)obj;
                            if (flag == true)
                                strOriValue = "Ya";
                            else
                                strOriValue = "Tidak";
                            break;
                        case "Decimal":
                            strOriValue = String.Format("{0:N}", Convert.ToDouble(obj));
                            break;
                        default:
                            strOriValue = obj.ToString();
                            break;
                    }
                }

                changeHistoryItem.OldValue = strOriValue;

                //if ((changeHistoryItem.FieldName == "AsetSMUP" || changeHistoryItem.FieldName == "AsetStamps" || changeHistoryItem.FieldName == "PendapatanSMUP" || changeHistoryItem.FieldName == "PendapatanVIS" || changeHistoryItem.FieldName == "KontrakVIS" || changeHistoryItem.FieldName == "BakiLejerSTS") && !string.IsNullOrEmpty(oriValue))
                //    changeHistoryItem.OldValue = String.Format("{0:N}", Convert.ToDouble(oriValue));

                changeHistoryItem.IsChanged = !(changeHistoryItem.OldValue == changeHistoryItem.NewValue);

            }

            if (oriHCLEmailBlastDetails != null)
            {
                //Insert change history if verify or reject button click 
                var emailblastOldStatus = AdminService.LookupParamSys.Where(x => x.LookupParamSysID == oriHCLEmailBlastDetails.EmailBlastStatusID).FirstOrDefault();
                if (vm.EmailBlastDetails.EmailBlastStatusID == (int)Constant.OutboundStatus.Disahkan)
                {
                    emailblastNewStatus = Constant.OutboundStatus.Disahkan.ToString();
                    vm.ChangeHistory.Add(BindChangeHistVM(vm.EmailBlastDetails.EmailDataID, "EmailBlastStatusID", "Status", emailblastOldStatus.ParamDesc, emailblastNewStatus, vm.EmailBlastDetails.JenisKempenID));
                }
                else if (vm.EmailBlastDetails.EmailBlastStatusID == (int)Constant.OutboundStatus.DitolakDipulangkan)
                {
                    emailblastNewStatus = Utilities.GetEnumDescription(Constant.OutboundStatus.DitolakDipulangkan);
                    vm.ChangeHistory.Add(BindChangeHistVM(vm.EmailBlastDetails.EmailDataID, "EmailBlastStatusID", "Status", emailblastOldStatus.ParamDesc, emailblastNewStatus, vm.EmailBlastDetails.JenisKempenID));
                }
            }

            lst = InsertEmailBlastChangeHistory(vm.ChangeHistory, vm.EmailBlastDetails.LastUpdatedByName, vm.EmailBlastDetails.LastUpdatedBy, vm.EmailBlastDetails.LastUpdatedDateTime);

            return lst;
        }

        public List<ChangeHistoryUpdateViewModel> VerifyEmailBlastData(OutboundParamViewModel vm, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            long i = 0;
            List<HCLEmailBlastUpdateViewModel> lstEmailBlastDetails = new List<HCLEmailBlastUpdateViewModel>();
            List<ChangeHistoryUpdateViewModel> lstHCLEmailBlastChgHistory = new List<ChangeHistoryUpdateViewModel>();
            // Retrieve orginal records for audit and change history 
            OutboundParamViewModel model = new OutboundParamViewModel();
            model.DataID = vm.DataID;
            model.JenisKempenID = vm.JenisKempenID;

            HCLEmailBlastDetailsViewModel oriHCLEmailBlastDetails = GetEmailBlastDetails(model);
            if (oriHCLEmailBlastDetails != null)
            {
                lstEmailBlastDetails.Add(new HCLEmailBlastUpdateViewModel { EmailDataID = vm.DataID.Value });

                i = repo.UpdateEmailBlastEmailDataStatus(lstEmailBlastDetails, (int)Constant.OutboundStatus.Disahkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);

                var emailblastOldStatus = AdminService.LookupParamSys.Where(x => x.LookupParamSysID == oriHCLEmailBlastDetails.EmailBlastStatusID).FirstOrDefault();
                var emailblastNewStatus = Constant.OutboundStatus.Disahkan.ToString();

                lstHCLEmailBlastChgHistory.Add(BindChangeHistVM(vm.DataID.Value, "EmailBlastStatusID", "Status", emailblastOldStatus.ParamDesc, emailblastNewStatus, vm.JenisKempenID.Value));
                repo.InsertEmailBlastChangeHistory(lstHCLEmailBlastChgHistory, strLastUpdatedByName, strLastUpdatedBy, dtLastUpdatedDateTime);

            }

            return lstHCLEmailBlastChgHistory;
        }

        public List<ChangeHistoryUpdateViewModel> RejectEmailBlastData(OutboundParamViewModel vm, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            long i = 0;
            List<HCLEmailBlastUpdateViewModel> lstEmailBlastDetails = new List<HCLEmailBlastUpdateViewModel>();
            List<ChangeHistoryUpdateViewModel> lstHCLEmailBlastChgHistory = new List<ChangeHistoryUpdateViewModel>();
            // Retrieve orginal records for audit and change history 
            OutboundParamViewModel model = new OutboundParamViewModel();
            model.DataID = vm.DataID;
            model.JenisKempenID = vm.JenisKempenID;

            HCLEmailBlastDetailsViewModel oriHCLEmailBlastDetails = GetEmailBlastDetails(model);
            if (oriHCLEmailBlastDetails != null)
            {
                lstEmailBlastDetails.Add(new HCLEmailBlastUpdateViewModel { EmailDataID = vm.DataID.Value });

                i = repo.UpdateEmailBlastEmailDataStatus(lstEmailBlastDetails, (int)Constant.OutboundStatus.DitolakDipulangkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);

                var emailblastOldStatus = AdminService.LookupParamSys.Where(x => x.LookupParamSysID == oriHCLEmailBlastDetails.EmailBlastStatusID).FirstOrDefault();
                var emailblastNewStatus = Utilities.GetEnumDescription(Constant.OutboundStatus.DitolakDipulangkan);

                lstHCLEmailBlastChgHistory.Add(BindChangeHistVM(vm.DataID.Value, "EmailBlastStatusID", "Status", emailblastOldStatus.ParamDesc, emailblastNewStatus, vm.JenisKempenID.Value));
                repo.InsertEmailBlastChangeHistory(lstHCLEmailBlastChgHistory, strLastUpdatedByName, strLastUpdatedBy, dtLastUpdatedDateTime);

                // Remove data from Email Blast Table when Email Data status is in schedule and Email Blast Status is in schedule
                if (oriHCLEmailBlastDetails.EmailBlastStatusID == (int)Constant.OutboundStatus.Dijadualkan)
                {
                    // Get current StatusID for from Email Blast Table
                    HCLEmailBlastUpdateViewModel emailblastdetail = new HCLEmailBlastUpdateViewModel();
                    emailblastdetail = repo.GetCurrentEmailBlastDetailStatus(vm.DataID.Value, vm.JenisKempenID.Value);
                    if (emailblastdetail != null)
                    {
                        if (emailblastdetail.EmailBlastStatusID == (int)Constant.OutboundStatus.Dijadualkan)
                        {
                            repo.DeleteEmailBlastAfterReject(vm.DataID.Value);
                        }
                    }
                }
            }

            return lstHCLEmailBlastChgHistory;
        }

        public ChangeHistoryUpdateViewModel BindChangeHistVM(long lngDataID, string strFieldName, string strDisplayName, string strOldValue, string strNewValue, int JenisKempenID)
        {
            ChangeHistoryUpdateViewModel changeHistVM = new ChangeHistoryUpdateViewModel();
            changeHistVM.ID = lngDataID;
            changeHistVM.FieldName = strFieldName;
            changeHistVM.DisplayName = strDisplayName;
            changeHistVM.OldValue = strOldValue;
            changeHistVM.NewValue = strNewValue;
            changeHistVM.IsChanged = !(changeHistVM.OldValue == changeHistVM.NewValue);
            changeHistVM.RefID = JenisKempenID.ToString();

            return changeHistVM;
        }

        public List<ChangeHistoryUpdateViewModel> InsertEmailBlastChangeHistory(List<ChangeHistoryUpdateViewModel> model, string strUserName, string strUserID, DateTime dtUpdated)
        {
            int intReturnValue = 0;
            List<ChangeHistoryUpdateViewModel> lst = model.Where(x => x.IsChanged).ToList();
            intReturnValue = repo.InsertEmailBlastChangeHistory(lst, strUserName, strUserID, dtUpdated);

            return lst;
        }

        public List<ChangeHistoryUpdateViewModel> VerifyDataByList(OutboundVerifyParamViewModel vm, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime, out long lngCount)
        {
            List<ChangeHistoryUpdateViewModel> lstChgHistory = new List<ChangeHistoryUpdateViewModel>();

            string strTrueDescription = Resources.Messages.TrueDescription;
            string strFalseDescription = Resources.Messages.FalseDescription;
            if (vm.IsSelectAll == true)
            {
                DataSet ds = new DataSet();
                if (vm.IsHCLEmailBlast == true)
                    ds = repo.GetSearchEmailBlastResult(vm.OutboundFilter);
                else
                    ds = repo.GetSearchOutboundResult(vm.OutboundFilter);

                dynamic lstresult = null;
                JArray arrResult = null;
                List<JToken> lstNew = new List<JToken>();
                if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                {
                    if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                        lstresult = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(ds.Tables[0]));

                    arrResult = JArray.Parse(lstresult.ToString());
                    if (vm.IsHCLEmailBlast == true)
                        lstNew = arrResult.Where(x => (int)x["EmailBlastStatusID"] == (int)Constant.OutboundStatus.Baru && (string.IsNullOrEmpty(x["HasError"].ToString()) ? x["HasError"].ToString() == string.Empty : Utilities.ConvertStringToBool(x["HasError"].ToString()) == false)).ToList();
                    else
                        lstNew = arrResult.Where(x => (int)x["StatusID"] == (int)Constant.OutboundStatus.Baru && (string.IsNullOrEmpty(x["HasError"].ToString()) ? x["HasError"].ToString() == string.Empty : Utilities.ConvertStringToBool(x["HasError"].ToString()) == false)).ToList();

                    if (lstNew.Count > 0)
                    {
                        if (vm.IsHCLEmailBlast == true)
                            lstChgHistory = VerifyEmailBlastAndInsertChangeHistory(null, lstNew, vm.JenisKempenID, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
                        else
                            lstChgHistory = VerifyOutboundAndInsertChangeHistory(null, lstNew, vm.JenisKempenID, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
                    }
                }
                lngCount = lstNew.Count;
                return lstChgHistory;
            }
            else
            {
                if (vm.IsHCLEmailBlast == true)
                {
                    List<HCLEmailBlastUpdateViewModel> lst = new List<HCLEmailBlastUpdateViewModel>();
                    for (int i = 0; i < vm.DataList.Count; i++)
                    {
                        HCLEmailBlastUpdateViewModel model = new HCLEmailBlastUpdateViewModel();
                        model.EmailDataID = vm.DataList[i].DataID;
                        lst.Add(model);
                    }

                    DataSet ds = new DataSet();
                    ds = repo.GetEmailBlastDataDetailsByList(lst);

                    List<HCLEmailBlastUpdateViewModel> lstUpdated = new List<HCLEmailBlastUpdateViewModel>();

                    if (ds != null && ds.Tables.Count > 0)
                    {
                        if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                        {
                            lstUpdated = repo.DataTableToList<HCLEmailBlastUpdateViewModel>(ds.Tables[0]).ToList();
                        }
                    }

                    lstUpdated = lstUpdated.Where(x => x.EmailBlastStatusID == (int)Constant.OutboundStatus.Baru && (x.HasError.HasValue ? x.HasError == false : !x.HasError.HasValue)).ToList();

                    if (lstUpdated.Count > 0)
                    {
                        lstChgHistory = VerifyEmailBlastAndInsertChangeHistory(lstUpdated, null, vm.JenisKempenID, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
                    }

                    lngCount = lstUpdated.Count;
                    return lstChgHistory;
                }
                else
                {
                    List<OutboundUpdateViewModel> lst = new List<OutboundUpdateViewModel>();
                    for (int i = 0; i < vm.DataList.Count; i++)
                    {
                        OutboundUpdateViewModel model = new OutboundUpdateViewModel();
                        model.ReMSDataID = vm.DataList[i].DataID;
                        model.JenisKempenId = vm.JenisKempenID;
                        lst.Add(model);
                    }

                    DataSet ds = new DataSet();
                    ds = repo.GetReMSDataDetailsByList(lst);

                    List<OutboundUpdateViewModel> lstUpdated = new List<OutboundUpdateViewModel>();

                    if (ds != null && ds.Tables.Count > 0)
                    {
                        if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                        {
                            lstUpdated = repo.DataTableToList<OutboundUpdateViewModel>(ds.Tables[0]).ToList();
                        }
                    }

                    lstUpdated = lstUpdated.Where(x => x.StatusID == (int)Constant.OutboundStatus.Baru && (x.HasError.HasValue ? x.HasError == false : !x.HasError.HasValue)).ToList();

                    if (lstUpdated.Count > 0)
                    {
                        lstChgHistory = VerifyOutboundAndInsertChangeHistory(lstUpdated, null, vm.JenisKempenID, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
                    }

                    lngCount = lstUpdated.Count;
                    return lstChgHistory;
                }
            }
        }

        private List<ChangeHistoryUpdateViewModel> VerifyOutboundAndInsertChangeHistory(List<OutboundUpdateViewModel> vm, List<JToken> lstNew, int intJenisKempenID, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            List<ChangeHistoryUpdateViewModel> lstChgHistory = new List<ChangeHistoryUpdateViewModel>();
            List<OutboundUpdateViewModel> lstVerifyOutbound = new List<OutboundUpdateViewModel>();

            string strReMSTableName = string.Empty;
            JenisKempenDetailViewModel jenisKempenDetails = new JenisKempenDetailViewModel();
            jenisKempenDetails = repo.GetJenisKempenDetailByID(intJenisKempenID, 0);

            strReMSTableName = jenisKempenDetails.ReMSTableName;

            dynamic list;
            if (vm != null)
                list = vm;
            else
                list = lstNew;

            int i = 0;
            string strNewStatus = Utilities.GetEnumDescription(Constant.OutboundStatus.Disahkan);
            string strOldStatus = Utilities.GetEnumDescription(Constant.OutboundStatus.Baru);

            for (i = 0; i < list.Count; i++)
            {
                if (vm != null)
                {
                    lstVerifyOutbound.Add(new OutboundUpdateViewModel { ReMSDataID = list[i].ReMSDataID });
                    lstChgHistory.Add(BindChangeHistVM(list[i].ReMSDataID, "StatusID", "Status", strOldStatus, strNewStatus, intJenisKempenID));
                }
                else
                {
                    lstVerifyOutbound.Add(new OutboundUpdateViewModel { ReMSDataID = (long)list[i]["DataID"] });
                    lstChgHistory.Add(BindChangeHistVM((long)list[i]["DataID"], "StatusID", "Status", strOldStatus, strNewStatus, intJenisKempenID));
                }
            }

            if (lstVerifyOutbound != null && lstChgHistory != null)
            {
                repo.UpdateOutboundReMSStatus(lstVerifyOutbound, strReMSTableName, (int)Constant.OutboundStatus.Disahkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
                repo.InsertChangeHistory(lstChgHistory, strLastUpdatedByName, strLastUpdatedBy, dtLastUpdatedDateTime);
            }

            return lstChgHistory;
        }

        private List<ChangeHistoryUpdateViewModel> VerifyEmailBlastAndInsertChangeHistory(List<HCLEmailBlastUpdateViewModel> vm, List<JToken> lstNew, int intJenisKempenID, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            List<ChangeHistoryUpdateViewModel> lstChgHistory = new List<ChangeHistoryUpdateViewModel>();
            List<HCLEmailBlastUpdateViewModel> lstVerifyEmailBlast = new List<HCLEmailBlastUpdateViewModel>();

            dynamic list;
            if (vm != null)
                list = vm;
            else
                list = lstNew;

            int i = 0;
            string strNewStatus = Utilities.GetEnumDescription(Constant.OutboundStatus.Disahkan);
            string strOldStatus = Utilities.GetEnumDescription(Constant.OutboundStatus.Baru);

            for (i = 0; i < list.Count; i++)
            {
                if (vm != null)
                {
                    lstVerifyEmailBlast.Add(new HCLEmailBlastUpdateViewModel { EmailDataID = list[i].EmailDataID });
                    lstChgHistory.Add(BindChangeHistVM(list[i].EmailDataID, "EmailBlastStatusID", "Status", strOldStatus, strNewStatus, intJenisKempenID));
                }
                else
                {
                    lstVerifyEmailBlast.Add(new HCLEmailBlastUpdateViewModel { EmailDataID = (long)list[i]["EmailDataID"] });
                    lstChgHistory.Add(BindChangeHistVM((long)list[i]["EmailDataID"], "EmailBlastStatusID", "Status", strOldStatus, strNewStatus, intJenisKempenID));
                }
            }

            if (lstVerifyEmailBlast != null && lstChgHistory != null)
            {
                repo.UpdateEmailBlastEmailDataStatus(lstVerifyEmailBlast, (int)Constant.OutboundStatus.Disahkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
                repo.InsertEmailBlastChangeHistory(lstChgHistory, strLastUpdatedByName, strLastUpdatedBy, dtLastUpdatedDateTime);
            }

            return lstChgHistory;
        }

        public List<ChangeHistoryUpdateViewModel> VerifyOutboundDataByBatch(ReMSDataPagedListViewModel vm, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime, out long lngCount)
        {
            DataSet ds = repo.GetNewReMSDataByBatchID(vm, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
            List<OutboundUpdateViewModel> lstNew = new List<OutboundUpdateViewModel>();
            List<ChangeHistoryUpdateViewModel> lstChgHistory = new List<ChangeHistoryUpdateViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                {
                    lstNew = repo.DataTableToList<OutboundUpdateViewModel>(ds.Tables[0]).ToList();
                }
            }

            if (lstNew.Count > 0)
            {
                int i = 0;
                string strOldStatus = Constant.OutboundStatus.Baru.ToString();
                string strNewStatus = Constant.OutboundStatus.Disahkan.ToString();

                string strReMSTableName = string.Empty;
                JenisKempenDetailViewModel jenisKempenDetails = new JenisKempenDetailViewModel();
                jenisKempenDetails = repo.GetJenisKempenDetailByID(vm.JenisKempenID, 0);

                strReMSTableName = jenisKempenDetails.ReMSTableName;

                for (i = 0; i < lstNew.Count; i++)
                {
                    lstChgHistory.Add(BindChangeHistVM(lstNew[i].ReMSDataID, "StatusID", "Status", strOldStatus, strNewStatus, vm.JenisKempenID));
                }

                repo.UpdateOutboundReMSStatus(lstNew, strReMSTableName, (int)Constant.OutboundStatus.Disahkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
                repo.InsertChangeHistory(lstChgHistory, strLastUpdatedByName, strLastUpdatedBy, dtLastUpdatedDateTime);
            }

            lngCount = lstNew.Count;
            return lstChgHistory;
        }

        public List<ChangeHistoryUpdateViewModel> VerifyEmailBlastDataByBatch(HCLEmailBlastDataPagedListViewModel vm, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime, out long lngCount)
        {
            DataSet ds = repo.GetNewEmailBlastDataByBatchID(vm.BatchID, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
            List<HCLEmailBlastUpdateViewModel> lstNew = new List<HCLEmailBlastUpdateViewModel>();
            List<ChangeHistoryUpdateViewModel> lstChgHistory = new List<ChangeHistoryUpdateViewModel>();

            if (ds != null && ds.Tables.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                {
                    lstNew = repo.DataTableToList<HCLEmailBlastUpdateViewModel>(ds.Tables[0]).ToList();
                }
            }

            if (lstNew.Count > 0)
            {
                int i = 0;
                string strOldStatus = Constant.OutboundStatus.Baru.ToString();
                string strNewStatus = Constant.OutboundStatus.Disahkan.ToString();

                for (i = 0; i < lstNew.Count; i++)
                {
                    lstChgHistory.Add(BindChangeHistVM(lstNew[i].EmailDataID, "StatusID", "Status", strOldStatus, strNewStatus, vm.JenisKempenID));
                }

                repo.UpdateEmailBlastEmailDataStatus(lstNew, (int)Constant.OutboundStatus.Disahkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
                repo.InsertEmailBlastChangeHistory(lstChgHistory, strLastUpdatedByName, strLastUpdatedBy, dtLastUpdatedDateTime);
            }

            lngCount = lstNew.Count;
            return lstChgHistory;
        }

        public string SendTestingEmail(EmailTestingViewModel vm, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime, out int outScheduleID, out DateTime outScheduleStartDate, out DateTime outScheduleExpiryDate, out string strEmail)
        {
            List<HCLEmailBlastUpdateViewModel> lstInsertEmailBlast = new List<HCLEmailBlastUpdateViewModel>();
            List<OutboundUpdateViewModel> lstInsertOutbound = new List<OutboundUpdateViewModel>();

            int intScheduleID = 0;
            DateTime dtScheduleStartDate = new DateTime();
            DateTime dtScheduleExpiryDate = new DateTime();
            DataTable dTblResultSchedule = new DataTable();

            if (vm.IsHCLEmailBlast)
                dTblResultSchedule = repo.UpdateEmailBlastScheduleByID(vm.Schedule, strLastUpdatedBy, dtLastUpdatedDateTime);
            else
                dTblResultSchedule = repo.UpdateOutboundScheduleByID(vm.Schedule, strLastUpdatedBy, dtLastUpdatedDateTime);


            if (dTblResultSchedule != null && dTblResultSchedule.Rows.Count > 0)
            {
                intScheduleID = Convert.ToInt32(dTblResultSchedule.Rows[0]["ScheduleID"]);
                dtScheduleStartDate = Convert.ToDateTime(dTblResultSchedule.Rows[0]["ScheduleStartDate"]);
                dtScheduleExpiryDate = Convert.ToDateTime(dTblResultSchedule.Rows[0]["ScheduleExpiryDate"]);
            }

            if (vm.IsSelectAll == true)
            {
                DataSet ds = new DataSet();

                if (vm.IsHCLEmailBlast)
                {
                    ds = repo.GetSearchEmailBlastResult(vm.OutboundFilter);
                    if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                    {
                        if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                        {
                            foreach (DataRow dr in ds.Tables[0].Rows)
                            {
                                HCLEmailBlastUpdateViewModel TempInsertEmailBlast = new HCLEmailBlastUpdateViewModel();

                                TempInsertEmailBlast.EmailDataID = Convert.ToInt64(dr["EmailDataID"]);
                                TempInsertEmailBlast.EmailBlastStatusID = (int)Constant.OutboundStatus.Dijadualkan;
                                TempInsertEmailBlast.JenisKempenId = vm.JenisKempenID;
                                TempInsertEmailBlast.Kategori1ID = vm.Kategori1ID;
                                TempInsertEmailBlast.Kategori2ID = vm.Kategori2ID;
                                TempInsertEmailBlast.Kategori3ID = vm.Kategori3ID;
                                TempInsertEmailBlast.CampaignID = vm.CampaignID;
                                TempInsertEmailBlast.EmailTemplateID = vm.EmailTemplateID;
                                TempInsertEmailBlast.InteractionChannelID = vm.InteractionChannelID;
                                TempInsertEmailBlast.IsTestingEmailBlast = true;
                                TempInsertEmailBlast.ScheduleID = intScheduleID;

                                lstInsertEmailBlast.Add(TempInsertEmailBlast);

                            }
                        }
                    }
                }
                else
                {
                    ds = repo.GetSearchOutboundResult(vm.OutboundFilter);
                    if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                    {
                        if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                        {
                            foreach (DataRow dr in ds.Tables[0].Rows)
                            {
                                OutboundUpdateViewModel TempInsertOutbound = new OutboundUpdateViewModel();

                                TempInsertOutbound.ReMSDataID = Convert.ToInt64(dr["DataID"]);
                                TempInsertOutbound.StatusID = (int)Constant.OutboundStatus.Dijadualkan;
                                TempInsertOutbound.JenisKempenId = vm.JenisKempenID;
                                TempInsertOutbound.Kategori1ID = vm.Kategori1ID;
                                TempInsertOutbound.Kategori2ID = vm.Kategori2ID;
                                TempInsertOutbound.Kategori3ID = vm.Kategori3ID;
                                TempInsertOutbound.CampaignID = vm.CampaignID;
                                TempInsertOutbound.EmailTemplateID = vm.EmailTemplateID;
                                TempInsertOutbound.ScheduleID = intScheduleID;

                                lstInsertOutbound.Add(TempInsertOutbound);
                            }
                        }
                    }
                }
            }
            else
            {
                if (vm.DataList.Count > 0)
                {

                    if (vm.IsHCLEmailBlast)
                    {
                        foreach (var item in vm.DataList)
                        {
                            HCLEmailBlastUpdateViewModel TempInsertEmailBlast = new HCLEmailBlastUpdateViewModel();

                            TempInsertEmailBlast.EmailDataID = item.DataID;
                            TempInsertEmailBlast.EmailBlastStatusID = (int)Constant.OutboundStatus.Dijadualkan;
                            TempInsertEmailBlast.JenisKempenId = vm.JenisKempenID;
                            TempInsertEmailBlast.Kategori1ID = vm.Kategori1ID;
                            TempInsertEmailBlast.Kategori2ID = vm.Kategori2ID;
                            TempInsertEmailBlast.Kategori3ID = vm.Kategori3ID;
                            TempInsertEmailBlast.CampaignID = vm.CampaignID;
                            TempInsertEmailBlast.EmailTemplateID = vm.EmailTemplateID;
                            TempInsertEmailBlast.InteractionChannelID = vm.InteractionChannelID;
                            TempInsertEmailBlast.IsTestingEmailBlast = true;
                            TempInsertEmailBlast.ScheduleID = intScheduleID;

                            lstInsertEmailBlast.Add(TempInsertEmailBlast);
                        }
                    }
                    else
                    {
                        foreach (var item in vm.DataList)
                        {
                            OutboundUpdateViewModel TempInsertOutbound = new OutboundUpdateViewModel();

                            TempInsertOutbound.ReMSDataID = item.DataID;
                            TempInsertOutbound.StatusID = (int)Constant.OutboundStatus.Dijadualkan;
                            TempInsertOutbound.JenisKempenId = vm.JenisKempenID;
                            TempInsertOutbound.Kategori1ID = vm.Kategori1ID;
                            TempInsertOutbound.Kategori2ID = vm.Kategori2ID;
                            TempInsertOutbound.Kategori3ID = vm.Kategori3ID;
                            TempInsertOutbound.CampaignID = vm.CampaignID;
                            TempInsertOutbound.EmailTemplateID = vm.EmailTemplateID;
                            TempInsertOutbound.ScheduleID = intScheduleID;

                            lstInsertOutbound.Add(TempInsertOutbound);
                        }
                    }
                }
            }

            if (lstInsertEmailBlast.Count > 0)
            {
                repo.InsertEmailBlastByList(lstInsertEmailBlast, strLastUpdatedBy, dtLastUpdatedDateTime);
            }

            if (lstInsertOutbound.Count > 0)
            {
                repo.InsertOutboundByList(lstInsertOutbound, strLastUpdatedBy, dtLastUpdatedDateTime, blnIsTestingEmail: true);
            }

            outScheduleID = intScheduleID;
            outScheduleStartDate = dtScheduleStartDate;
            outScheduleExpiryDate = dtScheduleExpiryDate;

            if (vm.IsHCLEmailBlast)
                strEmail = AdminService.ParameterSettings[2].ParameterValue;
            else
                strEmail = AdminService.ParameterSettings[3].ParameterValue;

            return strEmail;

            //if (vm.IsHCLEmailBlast)
            //    return lstInsertEmailBlast.Count;
            //else
            //    return lstInsertOutbound.Count;
        }

        public List<ChangeHistoryUpdateViewModel> RejectOutboundData(OutboundParamViewModel vm, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            long i = 0;
            List<OutboundUpdateViewModel> lstOutboundDetails = new List<OutboundUpdateViewModel>();
            List<ChangeHistoryUpdateViewModel> lstChgHistory = new List<ChangeHistoryUpdateViewModel>();
            // Retrieve orginal records for audit and change history 
            OutboundParamViewModel model = new OutboundParamViewModel();
            model.DataID = vm.DataID;
            model.JenisKempenID = vm.JenisKempenID;

            OutboundDetailsAnsuranViewModel oriOutboundDetailsAnsuran = new OutboundDetailsAnsuranViewModel();
            OutboundDetailsTunggakanViewModel oriOutboundDetailsTunggakan = new OutboundDetailsTunggakanViewModel();
            OutboundDetailsCTLViewModel oriOutboundDetailsCTL = new OutboundDetailsCTLViewModel();

            JenisKempenDetailViewModel objJenisKempenDetails = new JenisKempenDetailViewModel();
            objJenisKempenDetails = repo.GetJenisKempenDetailByID(vm.JenisKempenID.Value, 0);

            if (objJenisKempenDetails.JenisKempenKategoriSysID == (int)Constant.JenisKempenKategori.KesAnsuran)
            {
                oriOutboundDetailsAnsuran = GetOutboundDetails(model);
            }
            else if (objJenisKempenDetails.JenisKempenKategoriSysID == (int)Constant.JenisKempenKategori.KesCDLYDL)
            {
                oriOutboundDetailsTunggakan = GetOutboundDetails(model);
            }
            else
            {
                oriOutboundDetailsCTL = GetOutboundDetails(model);
            }

            if (oriOutboundDetailsAnsuran != null || oriOutboundDetailsTunggakan != null || oriOutboundDetailsCTL != null)
            {
                lstOutboundDetails.Add(new OutboundUpdateViewModel { ReMSDataID = vm.DataID.Value });
                i = repo.UpdateOutboundReMSStatus(lstOutboundDetails, objJenisKempenDetails.ReMSTableName, (int)Constant.OutboundStatus.DitolakDipulangkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime, vm.ReturnReasonID.Value);

                string strOldStatus;
                int intOriStatusID = 0;

                if (objJenisKempenDetails.JenisKempenKategoriSysID == (int)Constant.JenisKempenKategori.KesAnsuran)
                {
                    strOldStatus = AdminService.LookupParamSys.Where(x => x.LookupParamSysID == oriOutboundDetailsAnsuran.StatusID).FirstOrDefault()?.ParamDesc;
                    intOriStatusID = oriOutboundDetailsAnsuran.StatusID;
                }
                else if (objJenisKempenDetails.JenisKempenKategoriSysID == (int)Constant.JenisKempenKategori.KesCDLYDL)
                {
                    strOldStatus = AdminService.LookupParamSys.Where(x => x.LookupParamSysID == oriOutboundDetailsTunggakan.StatusID).FirstOrDefault()?.ParamDesc;
                    intOriStatusID = oriOutboundDetailsTunggakan.StatusID;
                }
                else
                {
                    strOldStatus = AdminService.LookupParamSys.Where(x => x.LookupParamSysID == oriOutboundDetailsCTL.StatusID).FirstOrDefault()?.ParamDesc;
                    intOriStatusID = oriOutboundDetailsCTL.StatusID;
                }

                string strNewStatus = Utilities.GetEnumDescription(Constant.OutboundStatus.DitolakDipulangkan);

                lstChgHistory.Add(BindChangeHistVM(vm.DataID.Value, "StatusID", "Status", strOldStatus, strNewStatus, vm.JenisKempenID.Value));
                repo.InsertChangeHistory(lstChgHistory, strLastUpdatedByName, strLastUpdatedBy, dtLastUpdatedDateTime);

                // Remove data from Outbound Table when ReMS Data status is Scheduled and Outbound status is Scheduled
                if (intOriStatusID == (int)Constant.OutboundStatus.Dijadualkan)
                {
                    // Get current StatusID from Outbound Table
                    OutboundUpdateViewModel outboundDetail = new OutboundUpdateViewModel();
                    outboundDetail = repo.GetCurrentOutboundDetailStatus(vm.DataID.Value, vm.JenisKempenID.Value);
                    if (outboundDetail != null)
                    {
                        if (outboundDetail.StatusID == (int)Constant.OutboundStatus.Dijadualkan)
                        {
                            repo.DeleteOutboundAfterReject(vm.DataID.Value);
                        }
                    }
                }
            }

            return lstChgHistory;
        }

        public List<ChangeHistoryUpdateViewModel> VerifyOutboundData(OutboundParamViewModel vm, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            long i = 0;
            List<OutboundUpdateViewModel> lstOutboundDetails = new List<OutboundUpdateViewModel>();
            List<ChangeHistoryUpdateViewModel> lstChgHistory = new List<ChangeHistoryUpdateViewModel>();
            // Retrieve orginal records for audit and change history 
            OutboundParamViewModel model = new OutboundParamViewModel();
            model.DataID = vm.DataID;
            model.JenisKempenID = vm.JenisKempenID;

            OutboundDetailsAnsuranViewModel oriOutboundDetailsAnsuran = new OutboundDetailsAnsuranViewModel();
            OutboundDetailsTunggakanViewModel oriOutboundDetailsTunggakan = new OutboundDetailsTunggakanViewModel();
            OutboundDetailsCTLViewModel oriOutboundDetailsCTL = new OutboundDetailsCTLViewModel();

            JenisKempenDetailViewModel objJenisKempenDetails = new JenisKempenDetailViewModel();
            objJenisKempenDetails = repo.GetJenisKempenDetailByID(vm.JenisKempenID.Value, 0);

            if (objJenisKempenDetails.JenisKempenKategoriSysID == (int)Constant.JenisKempenKategori.KesAnsuran)
            {
                oriOutboundDetailsAnsuran = GetOutboundDetails(model);
            }
            else if (objJenisKempenDetails.JenisKempenKategoriSysID == (int)Constant.JenisKempenKategori.KesCDLYDL)
            {
                oriOutboundDetailsTunggakan = GetOutboundDetails(model);
            }
            else
            {
                oriOutboundDetailsCTL = GetOutboundDetails(model);
            }

            if (oriOutboundDetailsAnsuran != null || oriOutboundDetailsTunggakan != null || oriOutboundDetailsCTL != null)
            {
                lstOutboundDetails.Add(new OutboundUpdateViewModel { ReMSDataID = vm.DataID.Value });
                i = repo.UpdateOutboundReMSStatus(lstOutboundDetails, objJenisKempenDetails.ReMSTableName, (int)Constant.OutboundStatus.Disahkan, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);

                string strOldStatus;
                int intOriStatusID = 0;

                if (objJenisKempenDetails.JenisKempenKategoriSysID == (int)Constant.JenisKempenKategori.KesAnsuran)
                {
                    strOldStatus = AdminService.LookupParamSys.Where(x => x.LookupParamSysID == oriOutboundDetailsAnsuran.StatusID).FirstOrDefault()?.ParamDesc;
                    intOriStatusID = oriOutboundDetailsAnsuran.StatusID;
                }
                else if (objJenisKempenDetails.JenisKempenKategoriSysID == (int)Constant.JenisKempenKategori.KesCDLYDL)
                {
                    strOldStatus = AdminService.LookupParamSys.Where(x => x.LookupParamSysID == oriOutboundDetailsTunggakan.StatusID).FirstOrDefault()?.ParamDesc;
                    intOriStatusID = oriOutboundDetailsTunggakan.StatusID;
                }
                else
                {
                    strOldStatus = AdminService.LookupParamSys.Where(x => x.LookupParamSysID == oriOutboundDetailsCTL.StatusID).FirstOrDefault()?.ParamDesc;
                    intOriStatusID = oriOutboundDetailsCTL.StatusID;
                }

                string strNewStatus = Utilities.GetEnumDescription(Constant.OutboundStatus.Disahkan);

                lstChgHistory.Add(BindChangeHistVM(vm.DataID.Value, "StatusID", "Status", strOldStatus, strNewStatus, vm.JenisKempenID.Value));
                repo.InsertChangeHistory(lstChgHistory, strLastUpdatedByName, strLastUpdatedBy, dtLastUpdatedDateTime);
            }

            return lstChgHistory;
        }

        public long CancelCampaignByID(OutboundCancelCampaignViewModel vm, string strLastUpdatedBy, string strLastUpdatedByName, DateTime dtLastUpdatedDateTime)
        {
            long i;
            if (vm.IsHCLEmailBlast == true)
            {
                i = repo.CancelEmailBlastCampaignByID(vm, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
            }
            else
            {
                i = repo.CancelOutboundCampaignByID(vm, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);
            }

            repo.UpdateCallingListByHisID(vm.HisID, vm.JenisKempenID, strLastUpdatedBy, strLastUpdatedByName, dtLastUpdatedDateTime);


            return i;
        }

        public byte[] ExportExcelOutboundListing(SearchOutboundPagedListViewModel paging)
        {
            DataSet ds;

            if (paging.IsHCLEmailBlast == true)
            {
                ds = repo.GetSearchEmailBlastResult(paging);
            }
            else
            {
                ds = repo.GetSearchOutboundResult(paging);
            }

            object lst = new List<SearchTPResultViewModel>();
            DataTable dtbl = new DataTable();
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                if (ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                {
                    dtbl = ds.Tables[0];
                }
            }

            return Utilities.ExportExcel(dtbl);
        }

    }
}
