using Exferia_Aplicacion.General;
using Exferia_Aplicacion.Herencia.Capas;
using Exferia_Aplicacion.Modelos_MantenimientoSimple;
using Exferia_CRM._0_Modelos;
using Exferia_EntityFramework;
using Exferia_General;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using static Exferia_Aplicacion.General.Enumerados;

namespace Exferia_CRM._1_Datos
{
    public class CRM_Terminales_Datos : ABS_Datos
    {
        #region Listado
        public List<INTERNO_CRM_Terminales_Listado_Modelo> g_lst_INTERNO_CRM_Terminales_Listado_Modelo = new List<INTERNO_CRM_Terminales_Listado_Modelo>();

        public override List<dynamic> Obtener_Listado(long _lng_idEmpresaSeleccionada, long _lng_idEjercicioActual, List<string> _lst_CamposConRelacionABuscar, List<INTERNO_Filtro_OpcionPadre_Modelo> _lst_INTERNO_Filtro_OpcionPadre_Modelo, List<INTERNO_Filtro_Modelo> _lst_INTERNO_Filtro_Modelo)
        {
            Exferia_Entities dbcontext = null;
            List<dynamic> lst_CRM = null;

            try
            {
                dbcontext = new Exferia_Entities();
                dbcontext.Configuration.LazyLoadingEnabled = false;

                // Consulta .....................................................
                ConsultaRellenar_Listado(dbcontext, _lng_idEmpresaSeleccionada, _lng_idEjercicioActual, Datos_Generales.GEN_Empresas_Devolver_EmpresasCompartidas_SegunFichero(_lng_idEmpresaSeleccionada, typeof(CRM_Terminales).Name), _lst_CamposConRelacionABuscar, -1, null, _lst_INTERNO_Filtro_OpcionPadre_Modelo, _lst_INTERNO_Filtro_Modelo);
                // ..............................................................

                if ((g_lst_INTERNO_CRM_Terminales_Listado_Modelo != null) && (g_lst_INTERNO_CRM_Terminales_Listado_Modelo.Count() > 0))
                {
                    lst_CRM = g_lst_INTERNO_CRM_Terminales_Listado_Modelo.Cast<dynamic>().ToList();
                }
            }
            catch (Exception ex)
            {
                throw new Control_Errores("", ex, nameof(CRM_Terminales_Datos) + "/" + nameof(Obtener_Listado), true);
            }
            finally
            {
                dbcontext.Database.Connection.Close();
                dbcontext.Dispose();
            }
            return lst_CRM;
        }
        public override dynamic Obtener_RegistroListado(long _lng_idEmpresaSeleccionada, long _lng_idEjercicioActual, List<string> _lst_CamposConRelacionABuscar, List<INTERNO_Filtro_OpcionPadre_Modelo> _lst_INTERNO_Filtro_OpcionPadre_Modelo, List<INTERNO_Filtro_Modelo> _lst_INTERNO_Filtro_Modelo, long _lng_id, List<long> _lst_id)
        {
            Exferia_Entities dbcontext = null;
            dynamic dnm_CRM = null;

            try
            {
                dbcontext = new Exferia_Entities();
                dbcontext.Configuration.LazyLoadingEnabled = false;

                // Consulta .....................................................
                ConsultaRellenar_Listado(dbcontext, _lng_idEmpresaSeleccionada, _lng_idEjercicioActual, Datos_Generales.GEN_Empresas_Devolver_EmpresasCompartidas_SegunFichero(_lng_idEmpresaSeleccionada, typeof(CRM_Terminales).Name), _lst_CamposConRelacionABuscar, _lng_id, _lst_id, _lst_INTERNO_Filtro_OpcionPadre_Modelo, _lst_INTERNO_Filtro_Modelo);
                // ..............................................................

                if ((g_lst_INTERNO_CRM_Terminales_Listado_Modelo != null) && (g_lst_INTERNO_CRM_Terminales_Listado_Modelo.Count() > 0))
                {
                    dnm_CRM = g_lst_INTERNO_CRM_Terminales_Listado_Modelo.Cast<dynamic>().ToList();
                }
            }
            catch (Exception ex)
            {
                throw new Control_Errores("", ex, nameof(CRM_Terminales_Datos) + "/" + nameof(Obtener_RegistroListado), true);
            }
            finally
            {
                dbcontext.Database.Connection.Close();
                dbcontext.Dispose();
            }
            return dnm_CRM;
        }
        protected override void ConsultaRellenar_Listado(Exferia_Entities _dbcontext, long _lng_idEmpresaSeleccionada, long _lng_idEjercicioActual, List<long> _lst_idEmpresasRelacionas, List<string> _lst_CamposConRelacionABuscar, long _lng_id, List<long> _lst_id, List<INTERNO_Filtro_OpcionPadre_Modelo> _lst_INTERNO_Filtro_OpcionPadre_Modelo, List<INTERNO_Filtro_Modelo> _lst_INTERNO_Filtro_Modelo)
        {
            var arr_idEmpresasRelacionas = _lst_idEmpresasRelacionas.ToArray();

            //Array de Ids para actualizar
            bool bol_Filtrar_ListadoIds = false;
            if (_lst_id != null && _lst_id.Count() > 0)
            {
                bol_Filtrar_ListadoIds = true;
            }
            var arr_ids = bol_Filtrar_ListadoIds ? _lst_id.ToArray() : new List<long>().ToArray();
            /*
            return (from obj_CRM_Terminales in _dbcontext.CRM_Terminales
                        //WHERE ..............................
                    where (obj_CRM_Terminales.fechaBorrado == null) &&
                          (
                            (obj_CRM_Terminales.idEmpresa==null) ||
                            (obj_CRM_Terminales.idEmpresa!=null && obj_CRM_Terminales.idEmpresa.Value.Equals(_lng_idEmpresaSeleccionada)) || 
                            (obj_CRM_Terminales.idEmpresa!= null && arr_idEmpresasRelacionas.Contains(obj_CRM_Terminales.idEmpresa.Value)) 
                          ) &&
                          ((bol_Filtrar_ListadoIds)
                            ? arr_ids.Contains(obj_CRM_Terminales.id)
                            : (_lng_id > -1 ? obj_CRM_Terminales.id.Equals(_lng_id) : 1 == 1)
                          )
                    select new INTERNO_CRM_Terminales_Listado_Modelo
                    {
                        id = obj_CRM_Terminales.id,
                        codigo = obj_CRM_Terminales.codigo,
                        descripcion = obj_CRM_Terminales.descripcion,
                        comunicacion_Tipo = obj_CRM_Terminales.comunicacion_Tipo,
                        comunicacion_Carencia = obj_CRM_Terminales.comunicacion_Carencia,
                        comunicacion_TiposEventos = obj_CRM_Terminales.comunicacion_TiposEventos,
                        gps_Tipo = obj_CRM_Terminales.gps_Tipo,
                        gps_Carencia = obj_CRM_Terminales.gps_Carencia,
                        gps_TiposEventos = obj_CRM_Terminales.gps_TiposEventos,
                        claveAdministracion = obj_CRM_Terminales.claveAdministracion,
                        permitirCrearClientes = obj_CRM_Terminales.permitirCrearClientes,
                        fechaBorrado = obj_CRM_Terminales.fechaBorrado,
                        idEmpleado = obj_CRM_Terminales.idEmpleado,
                        //Empleado
                        Empleado_Codigo = _lst_CamposConRelacionABuscar.Contains(nameof(INTERNO_CRM_Terminales_Listado_Modelo.Empleado)) ? obj_CRM_Terminales.MAE_Empleados.codigo : "",
                        Empleado_Descripcion = _lst_CamposConRelacionABuscar.Contains(nameof(INTERNO_CRM_Terminales_Listado_Modelo.Empleado)) ? obj_CRM_Terminales.MAE_Empleados.nombre : "",
                        Empleado_FechaBorrado = _lst_CamposConRelacionABuscar.Contains(nameof(INTERNO_CRM_Terminales_Listado_Modelo.Empleado)) ? obj_CRM_Terminales.MAE_Empleados.fechaBorrado : null,
                        
                    });*/
        }
        #endregion

        #region Listado Secundario
        public override List<dynamic> Obtener_Listado_Secundario(long _lng_idEmpresaSeleccionada, long _lng_idEjercicioActual, List<string> _lst_CamposConRelacionABuscar, List<INTERNO_Filtro_OpcionPadre_Modelo> _lst_INTERNO_Filtro_OpcionPadre_Modelo, List<INTERNO_Filtro_Modelo> _lst_INTERNO_Filtro_Modelo)
        {
            return null;
        }
        public override dynamic Obtener_RegistroListado_Secundario(long _lng_idEmpresaSeleccionada, long _lng_idEjercicioActual, List<string> _lst_CamposConRelacionABuscar, List<INTERNO_Filtro_OpcionPadre_Modelo> _lst_INTERNO_Filtro_OpcionPadre_Modelo, List<INTERNO_Filtro_Modelo> _lst_INTERNO_Filtro_Modelo, long _lng_id, List<long> _lst_ids)
        {
            return null;
        }
        protected override void ConsultaRellenar_Listado_Secundario(Exferia_Entities _obj_Exferia_Entities, long _lng_idEmpresaSeleccionada, long _lng_idEjercicioActual, List<long> _lst_idEmpresasRelacionadas, List<string> _lst_CamposConRelacionABuscar, long _lng_id, List<long> _lst_ids, List<INTERNO_Filtro_OpcionPadre_Modelo> _lst_INTERNO_Filtro_OpcionPadre_Modelo, List<INTERNO_Filtro_Modelo> _lst_INTERNO_Filtro_Modelo)
        { }
        #endregion

        #region F3
        private INTERNO_CRM_Terminales_Listado_Modelo g_mdl_INTERNO_CRM_Terminales_Listado_Modelo_F3 = null;

        public override dynamic Obtener_F3(string _str_filtro, string _str_CampoBusqueda, long _lng_idEmpresaSeleccionada, long _lng_idEjercicioActual, List<INTERNO_Filtro_OpcionPadre_Modelo> _lst_INTERNO_Filtro_OpcionPadre_Modelo, List<INTERNO_Filtro_Modelo> _lst_INTERNO_Filtro_Modelo)
        {
            Exferia_Entities dbcontext = null;
            dynamic dnm_CRM = null;

            try
            {
                dbcontext = new Exferia_Entities();
                dbcontext.Configuration.LazyLoadingEnabled = false;

                //Consulta ......................................................
                ConsultaRellenar_F3(dbcontext, _lng_idEmpresaSeleccionada, _lng_idEjercicioActual, Datos_Generales.GEN_Empresas_Devolver_EmpresasCompartidas_SegunFichero(_lng_idEmpresaSeleccionada, typeof(CRM_Terminales).Name), _str_CampoBusqueda, _str_filtro, -1, _lst_INTERNO_Filtro_OpcionPadre_Modelo, _lst_INTERNO_Filtro_Modelo);
                // ..............................................................

                if (g_mdl_INTERNO_CRM_Terminales_Listado_Modelo_F3 != null)
                {
                    dnm_CRM = g_mdl_INTERNO_CRM_Terminales_Listado_Modelo_F3;
                }
            }
            catch (Exception ex)
            {
                throw new Control_Errores("", ex, nameof(CRM_Terminales_Datos) + "/" + nameof(Obtener_F3), true);
            }
            finally
            {
                dbcontext.Database.Connection.Close();
                dbcontext.Dispose();
            }
            return dnm_CRM;
        }
        public override dynamic Obtener_F3_PorId(long _lng_id, long _lng_idEmpresaSeleccionada, long _lng_idEjercicioActual, List<INTERNO_Filtro_OpcionPadre_Modelo> _lst_INTERNO_Filtro_OpcionPadre_Modelo, List<INTERNO_Filtro_Modelo> _lst_INTERNO_Filtro_Modelo)
        {
            Exferia_Entities dbcontext = null;
            dynamic dnm_CRM = null;

            try
            {
                dbcontext = new Exferia_Entities();
                dbcontext.Configuration.LazyLoadingEnabled = false;

                //Conuslta ......................................................
                ConsultaRellenar_F3(dbcontext, _lng_idEmpresaSeleccionada, _lng_idEjercicioActual, Datos_Generales.GEN_Empresas_Devolver_EmpresasCompartidas_SegunFichero(_lng_idEmpresaSeleccionada, typeof(CRM_Terminales).Name), "", "", _lng_id, _lst_INTERNO_Filtro_OpcionPadre_Modelo, _lst_INTERNO_Filtro_Modelo);
                // ..............................................................

                if (g_mdl_INTERNO_CRM_Terminales_Listado_Modelo_F3 != null)
                {
                    dnm_CRM = g_mdl_INTERNO_CRM_Terminales_Listado_Modelo_F3;
                }
            }
            catch (Exception ex)
            {
                throw new Control_Errores("", ex, nameof(CRM_Terminales_Datos) + "/" + nameof(Obtener_F3_PorId), true);
            }
            finally
            {
                dbcontext.Database.Connection.Close();
                dbcontext.Dispose();
            }
            return dnm_CRM;
        }
        protected override void ConsultaRellenar_F3(Exferia_Entities _dbcontext, long _lng_idEmpresaSeleccionada, long _lng_idEjercicioActual, List<long> _lst_idEmpresasRelacionas, string _str_CampoBusqueda, string _str_Filtro, long _lng_id, List<INTERNO_Filtro_OpcionPadre_Modelo> _lst_INTERNO_Filtro_OpcionPadre_Modelo, List<INTERNO_Filtro_Modelo> _lst_INTERNO_Filtro_Modelo)
        {
            var arr_idEmpresasRelacionadas = _lst_idEmpresasRelacionas.ToArray();
            /*
            //Consulta
            return (from obj_CRM_Terminales in _dbcontext.CRM_Terminales
                    where obj_CRM_Terminales.fechaBorrado == null &&
                            (
                            (obj_CRM_Terminales.idEmpresa == null) ||
                            (obj_CRM_Terminales.idEmpresa != null && obj_CRM_Terminales.idEmpresa.Value.Equals(_lng_idEmpresaSeleccionada)) ||
                            (obj_CRM_Terminales.idEmpresa != null && arr_idEmpresasRelacionadas.Contains(obj_CRM_Terminales.idEmpresa.Value))
                          ) &&
                        (
                           _lng_id > -1
                                ? obj_CRM_Terminales.id == _lng_id
                                : (
                                        //Filtrar por Codigo
                                        (_str_CampoBusqueda.Equals(nameof(obj_CRM_Terminales.codigo)))
                                                ? obj_CRM_Terminales.codigo.Equals(_str_Filtro)
                                         //Filtrar por Descripcion
                                         : obj_CRM_Terminales.descripcion.Equals(_str_Filtro)
                                    )
                        )
                    select new INTERNO_CRM_Terminales_Listado_Modelo
                    {
                        id = obj_CRM_Terminales.id,
                        codigo = obj_CRM_Terminales.codigo,
                        descripcion = obj_CRM_Terminales.descripcion
                    }).Distinct();*/
        }

        #endregion

        #region Obtener
        public override dynamic Obtener(long _lng_id)
        {
            Exferia_Entities dbcontext = null;

            dynamic dnm_Terminales_Modelo = null;

            try
            {
                dbcontext = new Exferia_Entities();
                dbcontext.Configuration.LazyLoadingEnabled = false;

                //Consulta.....................................................................
                var consulta = (from obj_CRM_Terminales in dbcontext.CRM_Terminales
                                    .Include(nameof(CRM_Terminales.MAE_Empleados))
                                    .Include(nameof(CRM_Terminales.CRM_Encuestas))
                                    .Include(nameof(CRM_Terminales.GEN_Provincias))
                                    .Include(nameof(CRM_Terminales.CRM_ClientesPotenciales))
                                where obj_CRM_Terminales.fechaBorrado == null &&
                                      obj_CRM_Terminales.id.Equals(_lng_id)
                                select obj_CRM_Terminales);
                //............................................................................

                if (consulta != null && consulta.Count() > 0)
                {
                    //Convertir a Dynamic
                    dnm_Terminales_Modelo = consulta.FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                throw new Control_Errores("", ex, nameof(CRM_Terminales_Datos) + "/" + nameof(Obtener), true);
            }
            finally
            {
                dbcontext.Database.Connection.Close();
                dbcontext.Dispose();
            }
            return dnm_Terminales_Modelo;
        }
        public override dynamic Obtener_Registro_PorCampo(string _str_Filtro, string _str_CampoBusqueda, long _lng_idEmpresaSeleccionada, long _lng_idEjercicioActual)
        {
            throw new NotImplementedException();
        }
        #endregion

        #region Grabar
        public override INTERNO_ValorDevuelto_Modelo Grabar(object _mdl_obj)
        {
            Exferia_Entities dbcontext = null;
            INTERNO_ValorDevuelto_Modelo mdl_ValorDevuelto_Modelo = new INTERNO_ValorDevuelto_Modelo();
            mdl_ValorDevuelto_Modelo.TodoCorrecto = true;

            try
            {
                dbcontext = new Exferia_Entities();
                dbcontext.Configuration.LazyLoadingEnabled = false;

                CRM_Terminales mdl_CRM_Terminales_AGrabar = (CRM_Terminales)_mdl_obj;

                //Encuestas Relacionadas
                var arr_ids_Encuestas = mdl_CRM_Terminales_AGrabar.CRM_Encuestas.Select(x => x.id).ToArray();
                List<CRM_Encuestas> lst_CRM_Encuestas_Relacionados = dbcontext.CRM_Encuestas.Where(m => arr_ids_Encuestas.Contains(m.id)).ToList();

                //Provincias Relacionadas
                var arr_ids_Provincias = mdl_CRM_Terminales_AGrabar.GEN_Provincias.Select(x => x.id).ToArray();
                List<GEN_Provincias> lst_GEN_Provincias_Relacionados = dbcontext.GEN_Provincias.Where(m => arr_ids_Provincias.Contains(m.id)).ToList();

                //Clientes Relacionados
                var arr_ids_ClientesPotenciales = mdl_CRM_Terminales_AGrabar.CRM_ClientesPotenciales.Select(x => x.id).ToArray();
                List<CRM_ClientesPotenciales> lst_CRM_ClientesPotenciales_Relacionados = dbcontext.CRM_ClientesPotenciales.Where(m => arr_ids_ClientesPotenciales.Contains(m.id)).ToList();

                CRM_Terminales mdl_CRM_Terminales_Final = new CRM_Terminales();
                CRM_Terminales mdl_CRM_Terminales_DatosViejos = new CRM_Terminales();

                //Grabar Datos
                var valorDevuelto = dbcontext.CRM_Terminales
                                             .Include(nameof(CRM_Terminales.CRM_Encuestas))
                                             .Include(nameof(CRM_Terminales.GEN_Provincias))
                                             .Include(nameof(CRM_Terminales.CRM_ClientesPotenciales))
                                             .Where(m => m.id.Equals(mdl_CRM_Terminales_AGrabar.id));

                if (valorDevuelto != null && valorDevuelto.Count() > 0)
                {
                    //Tipo de Accion que se va a realizar
                    mdl_ValorDevuelto_Modelo.TipoAccion = Enumerados.G_ENUM_TIPOACCION.INT_MODIFICAR;

                    mdl_CRM_Terminales_Final = valorDevuelto.FirstOrDefault();

                    //Datos Auxiliares
                    var arr_ids_Old_Encuestas = mdl_CRM_Terminales_Final.CRM_Encuestas.Select(x => x.id).ToArray();
                    var arr_ids_Old_Provincias = mdl_CRM_Terminales_Final.GEN_Provincias.Select(x => x.id).ToArray();
                    var arr_ids_Old_ClientesPotenciales = mdl_CRM_Terminales_Final.CRM_ClientesPotenciales.Select(x => x.id).ToArray();

                    //Datos Viejos para la trazabilidad
                    Funciones.CopiarPropiedadesObjetos(mdl_CRM_Terminales_Final, mdl_CRM_Terminales_DatosViejos, false, false);

                    //Quitar las Encuestas que no esten relacionados
                    mdl_CRM_Terminales_Final.CRM_Encuestas.Where(m => (arr_ids_Encuestas.Count() == 0
                                                                         ? 1 == 1
                                                                         : (!arr_ids_Encuestas.Contains(m.id))) &&
                                                                            (arr_ids_Old_Encuestas.Count() == 0
                                                                            ? 1 == 1
                                                                            : (arr_ids_Old_Encuestas.Contains(m.id))
                                                                        )
                                                                        )
                                                            .ToList().ForEach(m => mdl_CRM_Terminales_Final.CRM_Encuestas.Remove(m));

                    //Quitar las Provincias que no esten relacionados
                    mdl_CRM_Terminales_Final.GEN_Provincias.Where(m => (arr_ids_Provincias.Count() == 0
                                                                         ? 1 == 1
                                                                         : (!arr_ids_Provincias.Contains(m.id))) &&
                                                                            (arr_ids_Old_Provincias.Count() == 0
                                                                            ? 1 == 1
                                                                            : (arr_ids_Old_Provincias.Contains(m.id))
                                                                        )
                                                                        )
                                                            .ToList().ForEach(m => mdl_CRM_Terminales_Final.GEN_Provincias.Remove(m));

                    //Quitar los ClientesPotenciales que no esten relacionados
                    mdl_CRM_Terminales_Final.CRM_ClientesPotenciales.Where(m => (arr_ids_ClientesPotenciales.Count() == 0
                                                                         ? 1 == 1
                                                                         : (!arr_ids_ClientesPotenciales.Contains(m.id))) &&
                                                                            (arr_ids_Old_ClientesPotenciales.Count() == 0
                                                                            ? 1 == 1
                                                                            : (arr_ids_Old_ClientesPotenciales.Contains(m.id))
                                                                        )
                                                                        )
                                                            .ToList().ForEach(m => mdl_CRM_Terminales_Final.CRM_ClientesPotenciales.Remove(m));

                    //Guardo en memoria las Encuestas que tenia en base de datos
                    List<CRM_Encuestas> lst_CRM_Terminales_Old = mdl_CRM_Terminales_Final.CRM_Encuestas.ToList();

                    //Guardo en memoria Las Provincias que tenia en base de datos
                    List<GEN_Provincias> lst_GEN_Provincias_Old = mdl_CRM_Terminales_Final.GEN_Provincias.ToList();

                    //Guardo en memoria Los ClientePotenciales que tenia en base de datos
                    List<CRM_ClientesPotenciales> lst_CRM_ClientesPotenciales_Old = mdl_CRM_Terminales_Final.CRM_ClientesPotenciales.ToList();

                    //Cargar los Datos Nuevos del Modelo
                    Funciones.CopiarPropiedadesObjetos(mdl_CRM_Terminales_AGrabar,mdl_CRM_Terminales_Final,false,false);

                    //Copio las Encuestas que tenia anteriormente
                    mdl_CRM_Terminales_Final.CRM_Encuestas = lst_CRM_Terminales_Old;

                    //Cargar las Encuestas nuevas en el modelo
                    Cargar_DatosModelo_Encuestas(mdl_CRM_Terminales_Final, false, lst_CRM_Encuestas_Relacionados);

                    //Copio las Provincias que tenia anteriormente
                    mdl_CRM_Terminales_Final.GEN_Provincias = lst_GEN_Provincias_Old;

                    //Cargar las Provincias nuevas en el modelo
                    Cargar_DatosModelo_Provincias(mdl_CRM_Terminales_Final, false, lst_GEN_Provincias_Relacionados);

                    //Copio Los Clientes Potenciales que tenia anteriormente
                    mdl_CRM_Terminales_Final.CRM_ClientesPotenciales = lst_CRM_ClientesPotenciales_Old;

                    //Cargar Los ClientesPotenciales nuevas en el modelo
                    Cargar_DatosModelo_ClientesPotenciales(mdl_CRM_Terminales_Final, false, lst_CRM_ClientesPotenciales_Relacionados);
                }
                else
                {
                    //Tipo de Accion que se va a realizar
                    mdl_ValorDevuelto_Modelo.TipoAccion = Enumerados.G_ENUM_TIPOACCION.INT_INSERTAR;

                    //Cargar los Datos Del Modelo
                    Funciones.CopiarPropiedadesObjetos(mdl_CRM_Terminales_AGrabar, mdl_CRM_Terminales_Final, false, false);

                    //Cargar las Encuestas en el Modelo
                    Cargar_DatosModelo_Encuestas(mdl_CRM_Terminales_Final, true, lst_CRM_Encuestas_Relacionados);

                    //Cargar las Provincias en el Modelo
                    Cargar_DatosModelo_Provincias(mdl_CRM_Terminales_Final, true, lst_GEN_Provincias_Relacionados);

                    //Cargar los ClientesPotenciales en el Modelo
                    Cargar_DatosModelo_ClientesPotenciales(mdl_CRM_Terminales_Final, true, lst_CRM_ClientesPotenciales_Relacionados);

                    dbcontext.CRM_Terminales.Add(mdl_CRM_Terminales_Final);
                }
                dbcontext.SaveChanges();

                //Grabar un registro de trazabilidad con los datos de la transaccion ralizada
                Datos_Generales.USR_Trazabilidad_Grabar(typeof(CRM_Terminales), mdl_CRM_Terminales_DatosViejos, mdl_CRM_Terminales_Final, mdl_ValorDevuelto_Modelo.TipoAccion, dbcontext);

                //Sincronizacion CRM
                if (Variables.G_BOL_CONEXION_SINCRONIZACIONCRM_ACTIVA)
                {
                    Sincronizar_CRM(mdl_CRM_Terminales_Final.id, false);
                }

                //Devolver tambien el Objeto
                mdl_ValorDevuelto_Modelo.Id = mdl_CRM_Terminales_Final.id;
            }
            catch (Exception ex)
            {
                throw new Control_Errores("", ex, nameof(CRM_Terminales_Datos) + "/" + nameof(Grabar), true);
            }
            finally
            {
                //Finalizar transaccion
                dbcontext.Database.Connection.Close();
                dbcontext.Dispose();
            }

            return mdl_ValorDevuelto_Modelo;
        }
        private void Cargar_DatosModelo_Encuestas(CRM_Terminales _mdl_CRM_Terminales, bool _bol_Nuevo, List<CRM_Encuestas> _lst_CRM_EncuestasRelacionadas)
        {
            //Cargar las Encuestas
            //Es un Registro nuevo
            if (_bol_Nuevo)
            {
                if(_lst_CRM_EncuestasRelacionadas != null && _lst_CRM_EncuestasRelacionadas.Count > 0)
                {
                    foreach(CRM_Encuestas mdl_CRM_Encuestas in _lst_CRM_EncuestasRelacionadas)
                    {
                        _mdl_CRM_Terminales.CRM_Encuestas.Add(mdl_CRM_Encuestas);
                    }
                }
            }
            //Se esta Modificando
            else
            {
                if(_lst_CRM_EncuestasRelacionadas != null && _lst_CRM_EncuestasRelacionadas.Count > 0)
                {
                    if(_mdl_CRM_Terminales.CRM_Encuestas.Count > 0)
                    {
                        //Añadir Registros Nuevos
                        foreach(CRM_Encuestas mdl_CRM_Encuestas in _lst_CRM_EncuestasRelacionadas)
                        {
                            if(_mdl_CRM_Terminales.CRM_Encuestas.Where(m=> m.id.Equals(mdl_CRM_Encuestas.id)).FirstOrDefault() == null)
                            {
                                _mdl_CRM_Terminales.CRM_Encuestas.Add(mdl_CRM_Encuestas);
                            }
                        }
                    }
                    else
                    {
                        foreach(CRM_Encuestas mdl_CRM_Encuestas in _lst_CRM_EncuestasRelacionadas)
                        {
                            _mdl_CRM_Terminales.CRM_Encuestas.Add(mdl_CRM_Encuestas);
                        }
                    }
                }
                //Si no hay registro seleccionados se vacia toda la relacion
                else
                {
                    _mdl_CRM_Terminales.CRM_Encuestas.Clear();
                }
            }
        }
        private void Cargar_DatosModelo_Provincias(CRM_Terminales _mdl_CRM_Terminales, bool _bol_Nuevo, List<GEN_Provincias> _lst_GEN_ProvinciasRelacionadas)
        {
            // Cargar las Provincias
            //Es un Registro nuevo
            if (_bol_Nuevo)
            {
                if (_lst_GEN_ProvinciasRelacionadas != null && _lst_GEN_ProvinciasRelacionadas.Count > 0)
                {
                    foreach (GEN_Provincias mdl_GEN_Provincias in _lst_GEN_ProvinciasRelacionadas)
                    {
                        _mdl_CRM_Terminales.GEN_Provincias.Add(mdl_GEN_Provincias);
                    }
                }
            }
            //Se esta Modificando
            else
            {
                if (_lst_GEN_ProvinciasRelacionadas != null && _lst_GEN_ProvinciasRelacionadas.Count > 0)
                {
                    if (_mdl_CRM_Terminales.GEN_Provincias.Count > 0)
                    {
                        //Añadir Registros Nuevos
                        foreach (GEN_Provincias mdl_GEN_Provincias in _lst_GEN_ProvinciasRelacionadas)
                        {
                            if (_mdl_CRM_Terminales.GEN_Provincias.Where(m => m.id.Equals(mdl_GEN_Provincias.id)).FirstOrDefault() == null)
                            {
                                _mdl_CRM_Terminales.GEN_Provincias.Add(mdl_GEN_Provincias);
                            }
                        }
                    }
                    else
                    {
                        foreach (GEN_Provincias mdl_GEN_Provincias in _lst_GEN_ProvinciasRelacionadas)
                        {
                            _mdl_CRM_Terminales.GEN_Provincias.Add(mdl_GEN_Provincias);
                        }
                    }
                }
                //Si no hay registro seleccionados se vacia toda la relacion
                else
                {
                    _mdl_CRM_Terminales.GEN_Provincias.Clear();
                }
            }
        }
        private void Cargar_DatosModelo_ClientesPotenciales(CRM_Terminales _mdl_CRM_Terminales, bool _bol_Nuevo, List<CRM_ClientesPotenciales> _lst_CRM_ClientesPotenciales)
        {
            // Cargar las Provincias
            //Es un Registro nuevo
            if (_bol_Nuevo)
            {
                if (_lst_CRM_ClientesPotenciales != null && _lst_CRM_ClientesPotenciales.Count > 0)
                {
                    foreach (CRM_ClientesPotenciales mdl_CRM_ClientesPotenciales in _lst_CRM_ClientesPotenciales)
                    {
                        _mdl_CRM_Terminales.CRM_ClientesPotenciales.Add(mdl_CRM_ClientesPotenciales);
                    }
                }
            }
            //Se esta Modificando
            else
            {
                if (_lst_CRM_ClientesPotenciales != null && _lst_CRM_ClientesPotenciales.Count > 0)
                {
                    if (_mdl_CRM_Terminales.CRM_ClientesPotenciales.Count > 0)
                    {
                        //Añadir Registros Nuevos
                        foreach (CRM_ClientesPotenciales mdl_CRM_ClientesPotenciales in _lst_CRM_ClientesPotenciales)
                        {
                            if (_mdl_CRM_Terminales.CRM_ClientesPotenciales.Where(m => m.id.Equals(mdl_CRM_ClientesPotenciales.id)).FirstOrDefault() == null)
                            {
                                _mdl_CRM_Terminales.CRM_ClientesPotenciales.Add(mdl_CRM_ClientesPotenciales);
                            }
                        }
                    }
                    else
                    {
                        foreach (CRM_ClientesPotenciales mdl_CRM_ClientesPotenciales in _lst_CRM_ClientesPotenciales)
                        {
                            _mdl_CRM_Terminales.CRM_ClientesPotenciales.Add(mdl_CRM_ClientesPotenciales);
                        }
                    }
                }
                //Si no hay registro seleccionados se vacia toda la relacion
                else
                {
                    _mdl_CRM_Terminales.CRM_ClientesPotenciales.Clear();
                }
            }
        }
        #endregion

        #region Borrar
        public override INTERNO_ValorDevuelto_Modelo Borrar(long _lng_id)
        {
            INTERNO_ValorDevuelto_Modelo mdl_ValorDevuelto_Modelo = new INTERNO_ValorDevuelto_Modelo();
            mdl_ValorDevuelto_Modelo.TodoCorrecto = true;
            //Tipo de Accion que se va a realizar
            mdl_ValorDevuelto_Modelo.TipoAccion = Enumerados.G_ENUM_TIPOACCION.INT_ELIMINAR;

            CRM_Terminales mdl_CRM_Terminales_Final = null;
            bool bol_ActializarFechaBorrrado = false;//Este campo se utiliza por si no se puede borrar, que actualice la fecha de borrado

            //ids para Sincronizacion
            long lng_idTerminal = -1;

            //Se utiliza la transaccion por la llamada al procedimiento almacenado
            using (TransactionScope transaccion_SQL = new TransactionScope(TransactionScopeOption.Required))
            {
                try
                {
                    //Primer Intento de Borrado
                    using (Exferia_Entities dbcontext = new Exferia_Entities())
                    {
                        dbcontext.Configuration.LazyLoadingEnabled = false;

                        var valorDevuelto = dbcontext.CRM_Terminales.Where(m => m.id.Equals(_lng_id));
                        if (valorDevuelto != null && valorDevuelto.Count() > 0)
                        {
                            mdl_CRM_Terminales_Final = valorDevuelto.FirstOrDefault();

                            //Rellenar ids para Sincronizacion
                            lng_idTerminal = mdl_CRM_Terminales_Final.id;

                            //Se intenta borrar, si diera un error porque esta relacionado se graba la fecha de baja
                            try
                            {
                                //Si no existe relaciones borramos la ubicacion
                                dbcontext.CRM_Terminales.Remove(mdl_CRM_Terminales_Final);
                                dbcontext.SaveChanges();

                                //Grabar un registro de trazabilidad con los datos de la transaccion realizada.
                                Datos_Generales.USR_Trazabilidad_Grabar(typeof(CRM_Terminales), null, mdl_CRM_Terminales_Final, G_ENUM_TIPOACCION.INT_ELIMINAR, dbcontext);
                            }
                            catch (Exception ex)
                            {
                                var sqlException = ex.GetBaseException() as SqlException;
                                if (sqlException != null)
                                {
                                    if (sqlException.Errors.Count > 0)
                                    {
                                        switch (sqlException.Errors[0].Number)
                                        {
                                            case Control_Errores.G_INT_ERRORCONTROLADO_BORRAR_CONFLICTO_CLAVEFORANEA: //Foreign Key Violation
                                                bol_ActializarFechaBorrrado = true;
                                                break;
                                            default:
                                                throw;
                                        }
                                    }
                                }
                                else
                                {
                                    throw;
                                }
                            }
                        }
                    }

                    //Actualizar la fecha de baja, al no poder borrarlo por tener relaciones
                    if (bol_ActializarFechaBorrrado)
                    {
                        using (Exferia_Entities dbcontext = new Exferia_Entities())
                        {
                            dbcontext.Configuration.LazyLoadingEnabled = false;

                            var valorDevuelto = dbcontext.CRM_Terminales.Where(m => m.id.Equals(_lng_id));
                            if (valorDevuelto != null && valorDevuelto.Count() > 0)
                            {
                                mdl_CRM_Terminales_Final = valorDevuelto.FirstOrDefault();

                                //Rellenar ids para Sincronizacion
                                lng_idTerminal = mdl_CRM_Terminales_Final.id;

                                //Se graba la fecha de baja
                                mdl_CRM_Terminales_Final.fechaBorrado = DateTime.Now;
                                dbcontext.SaveChanges();

                                //Grabar un registro de trazabiidad con los datos de la transaccion realizada
                                Datos_Generales.USR_Trazabilidad_Grabar(typeof(CRM_Terminales), null, mdl_CRM_Terminales_Final, G_ENUM_TIPOACCION.INT_ELIMINAR, dbcontext);
                            }
                        }
                    }

                    //Sincronizar datos para descarga
                    //CRM
                    if (Variables.G_BOL_CONEXION_SINCRONIZACIONCRM_ACTIVA)
                    {
                        Sincronizar_CRM(lng_idTerminal, true);
                    }

                    //Devolver tambien el objeto
                    mdl_ValorDevuelto_Modelo.Id = mdl_CRM_Terminales_Final.id;

                    // Se termina la Transaccion Correctamente
                    transaccion_SQL.Complete();
                }
                catch (Exception ex)
                {
                    throw new Control_Errores("", ex, nameof(CRM_Terminales_Datos) + "/" + nameof(Borrar), true);
                }
                finally
                {
                    // Finalizar transaccion
                    transaccion_SQL.Dispose();
                }
            }
            return mdl_ValorDevuelto_Modelo;
        }
        public override INTERNO_ValorDevuelto_Modelo Borrar(long _lng_id, long _lng_idAuxiliar)
        {
            throw new NotImplementedException();
        }
        public override INTERNO_ValorDevuelto_Modelo Borrar(object _mdl_obj)
        {
            throw new NotImplementedException();
        }
        #endregion   

        #region Procedimiento Almacenados para Sincronizacion
        public INTERNO_ValorDevuelto_Modelo Sincronizar_CRM(long _lng_idTerminal, bool _bol_Borrado)
        {
            Exferia_Entities dbcontext = null;
            INTERNO_ValorDevuelto_Modelo mdl_ValorDevuelto_Modelo = new INTERNO_ValorDevuelto_Modelo();
            mdl_ValorDevuelto_Modelo.TodoCorrecto = true;

            try
            {
                dbcontext = new Exferia_Entities();
                dbcontext.Configuration.LazyLoadingEnabled = false;
                
                dbcontext.P_CRM_Sincronizar_UnRegistro_1_CRM_Terminales(_lng_idTerminal, _bol_Borrado);
            }
            catch (Exception ex)
            {
                throw new Control_Errores("", ex, nameof(CRM_Terminales_Datos) + "/" + nameof(Sincronizar_CRM), true);
            }
            finally
            {
                // Finalizar transaccion
                dbcontext.Database.Connection.Close();
                dbcontext.Dispose();
            }

            return mdl_ValorDevuelto_Modelo;
        }
        #endregion
    }
}
