private void RefreshAndBindInfo()
        {
            if (!User.Identity.IsAuthenticated)
            {
                FormsAuthentication.SignOut();
                return;
            }

            if (Session["reconversionMonetaria.cantidadDigitos"] == null ||
                Session["reconversionMonetaria.ano"] == null ||
                Session["reconversionMonetaria.cuentaContableID"] == null)
            {
                string errorMessage = "Aparentemente, Ud. no ha indicado un filtro (parámetros de ejecución) aún; o lo ha indicado de manera <em>incompleta</em>.<br />" +
                                      "Ud. debe abrir la página que muestra el filtro e indicar valores para todos los parámetros de ejecución de este proceso.";

                this.ErrMessage_Span.InnerHtml = errorMessage;
                this.ErrMessage_Span.Visible   = true;

                return;
            }

            dbContab_Contab_Entities context = new dbContab_Contab_Entities();

            // leemos la cuenta contable indicada por el usuaio
            int             cuentaContableID = Convert.ToInt32(Session["reconversionMonetaria.cuentaContableID"]);
            CuentasContable cuentaContable   = context.CuentasContables.Where(c => c.ID == cuentaContableID).FirstOrDefault();

            if (cuentaContable == null)
            {
                string errorMessage = "Error: no hemos podido leer la cuenta contable indicada en el filtro.</em>.<br />" +
                                      "Por favor revise. La cuenta contable indicada debe existir en la tabla de cuentas contables.";

                this.ErrMessage_Span.InnerHtml = errorMessage;
                this.ErrMessage_Span.Visible   = true;

                return;
            }

            // debe existir una moneda 'nacional'; solo para ésta haremos la reconversión ...
            var monedaNacional_array = context.Monedas.Where(m => m.NacionalFlag);

            if (monedaNacional_array == null)
            {
                string errorMessage = "Error: aparentemente, no se ha definido una de las monedas como <em>nacional</em>.<br />" +
                                      "Ud. debe revisar la tabla de monedas y asegurarse que una de ellas sea definida como <em>nacional</em>.";

                this.ErrMessage_Span.InnerHtml = errorMessage;
                this.ErrMessage_Span.Visible   = true;

                return;
            }

            if (monedaNacional_array.Count() > 1)
            {
                string errorMessage = "Error: aparentemente, más de una moneda ha sido definida del tipo <em>nacional</em>.<br />" +
                                      "Ud. debe revisar la tabla de monedas y asegurarse que <b>solo una de ellas</b> sea definida como <em>nacional</em>.";

                this.ErrMessage_Span.InnerHtml = errorMessage;
                this.ErrMessage_Span.Visible   = true;

                return;
            }

            Moneda monedaNacional = monedaNacional_array.First();

            var cia = context.tCiaSeleccionadas.Where(s => s.UsuarioLS == User.Identity.Name).
                      Select(c => new { ciaContabSeleccionada = c.Compania.Numero }).
                      FirstOrDefault();

            short ano = Convert.ToInt16(Session["reconversionMonetaria.ano"]);

            // leemos los asientos del año, para asegurarnos que no hay asientos descuadrados ...
            string sSqlQueryString =
                "SELECT Count(*) As partidas " +
                "FROM dAsientos d Inner Join Asientos a On d.NumeroAutomatico = a.NumeroAutomatico " +
                "Where a.AnoFiscal = {0} And a.Moneda = {1} And a.Cia = {2} " +
                "Group By d.NumeroAutomatico " +
                "Having Sum(d.Debe) <> Sum(d.Haber)";

            List <int> asientosDescuadrados = context.ExecuteStoreQuery <int>(sSqlQueryString, ano, monedaNacional.Moneda1, cia.ciaContabSeleccionada).ToList();

            if (asientosDescuadrados.Count() > 0)
            {
                // nota: esta situación no aborta el proceso, pues debe ser el resultado del 1er. paso de la reconversión ...
                string errorMessage = "Advertencia: existen asientos descuadrados para el año a reconvertir.<br />" +
                                      "Ud. debe continuar con el próximo paso y ajustarlos, <b>solo</b> si estos asientos son producto del 1er. paso de la reconversión.";

                this.ErrMessage_Span.InnerHtml = errorMessage;
                this.ErrMessage_Span.Visible   = true;
            }

            Int16 cantidadDigitos = Convert.ToInt16(Session["reconversionMonetaria.cantidadDigitos"]);

            // finalmente, determinamos el divisor para la reconversión: si, por ejemplo, la cantidad de dígitos es 3, el dividor debe ser 1.000
            int divisor = 1;

            for (short i = 1; i <= cantidadDigitos; i++)
            {
                divisor = divisor * 10;
            }

            this.monedaNacional_span.InnerText  = monedaNacional.Descripcion + " (" + monedaNacional.Simbolo + ")";
            this.cuentaContable_span.InnerText  = $"{cuentaContable.CuentaEditada} - {cuentaContable.Descripcion} - {cuentaContable.ID.ToString()}";
            this.ano_span.InnerText             = ano.ToString();
            this.cantidadDigitos_span.InnerText = cantidadDigitos.ToString();
            this.divisor_span.InnerText         = divisor.ToString("N0");

            this.texto1.Visible = false;

            this.texto1.Visible = true;
            this.ejecutarReconversion_button.Visible = true;

            parametrosProc parametrosProc = new parametrosProc
            {
                ano                   = ano,
                moneda                = monedaNacional.Moneda1,
                cantidadDigitos       = cantidadDigitos,
                divisor               = divisor,
                cuentaContableID      = cuentaContable.ID,
                ciaContabSeleccionada = cia.ciaContabSeleccionada,
            };

            // la idea es mantener el state de estos parámetros para tenerlos siempre a la mano ...
            Session["parametrosProc"] = parametrosProc;
        }
    private void CopiarMontosEntreCias()
    {
        // construimos el nombre del archivo xml que contendrá, al final, los resultados de la ejecución
        String fileName = String.Concat(Page.GetType().Name, "-", User.Identity.Name);
        String rootPath = Server.MapPath("~");
        String filePath = Server.MapPath("~/keepstatefiles/" + fileName + ".xml");

        // -----------------------------------------------------------------------------------------------
        // nótese que creamos el xml file que contendrá los resultados del proceso ahora. Esto permitirá
        // actualizarlo más adelante cuando sea necesario en forma más compacta (ie: sin crear todo el
        // archivo cada vez que, por ejemplo, encontremos un error y necesitemos reportarlo

        XElement root = new XElement("ProcessState",
                                     new XElement("Values",
                                                  new XElement("CantidadCodigosEliminados", 0),
                                                  new XElement("CantidadCodigosCopiados", 0),
                                                  new XElement("CantidadCuentasContablesAsociadasCopiadas", 0),
                                                  new XElement("CantidadCuentasContablesAsociadasNoCopiadas", 0),
                                                  new XElement("CantidadRegistrosMontosCopiados", 0),

                                                  new XElement("Error",
                                                               new XElement("ErrorFlag", 0),
                                                               new XElement("ErrorMessage", ""))));

        root.Save(filePath);
        // -----------------------------------------------------------------------------------------------


        // contamos y eliminamos los registros que ahora puedan existir para la cia Target. Nótese que, de
        // existir, ya chequeamos que el usuario haya marcado la opción que permite eliminarlos.

        dbContabDataContext dbContab = new dbContabDataContext();

        int nCantidadCodigosEliminados = (from a in dbContab.Presupuesto_Codigos
                                          where a.CiaContab == int.Parse(TargetCiaContab_ListBox.SelectedValue)
                                          select a.Codigo).Count();

        // ----------------------------------------------------------------------------------------------
        // siempre eliminamos los registros de códigos que puedan existir para la compañía Target;
        // lo hacemos pues, si existen códigos por eliminar, al llegar aquí SIEMPRE se tuvo que haber
        // marcado que éstos debían ser eliminados

        dbContab.ExecuteCommand("Delete From Presupuesto_Codigos Where CiaContab = {0}", TargetCiaContab_ListBox.SelectedValue);

        // para reportar el progreso en la página

        int nRegistroActual = 0, nProgressPercentaje = 0, nCantidadRegistros = 0;

        nCantidadRegistros = (from sc in dbContab.Presupuesto_Codigos
                              where sc.CiaContab ==
                              int.Parse(SourceCiaContab_ListBox.SelectedValue)
                              select sc).Count();

        // ----------------------------------------------------------------------------------------------
        // leemos los códigos de presupuesto de la compañía Source y los copiamos a la compañía Target ...

        int nCantidadCodigosCopiados = 0;

        var SourceCia_CodigosPresuesto = from sc in dbContab.Presupuesto_Codigos
                                         where sc.CiaContab == int.Parse(SourceCiaContab_ListBox.SelectedValue)
                                         select new
        {
            sc.Codigo,
            sc.Descripcion,
            sc.CantNiveles,
            sc.GrupoFlag,
            sc.SuspendidoFlag
        };

        Presupuesto_Codigo        MyCodigo;
        List <Presupuesto_Codigo> MyCodigo_List = new List <Presupuesto_Codigo>();

        foreach (var Codigo in SourceCia_CodigosPresuesto)
        {
            // vamos agregando cada código leído de la compañía Source a la compañía Target
            MyCodigo = new Presupuesto_Codigo();

            MyCodigo.Codigo         = Codigo.Codigo;
            MyCodigo.Descripcion    = Codigo.Descripcion;
            MyCodigo.CantNiveles    = Codigo.CantNiveles;
            MyCodigo.GrupoFlag      = Codigo.GrupoFlag;
            MyCodigo.SuspendidoFlag = Codigo.SuspendidoFlag;
            MyCodigo.CiaContab      = int.Parse(TargetCiaContab_ListBox.SelectedValue);

            MyCodigo_List.Add(MyCodigo);

            nCantidadCodigosCopiados++;

            // ---------------------------------------------------------------------
            // calculamos el progreso (%); es usado por el progress bar en la página
            nRegistroActual++;
            nProgressPercentaje = nRegistroActual * 100 / nCantidadRegistros;

            Session["Progress_Percentage"] = nProgressPercentaje;
            // ----------------------------------------------------------------------
        }

        try
        {
            dbContab.Presupuesto_Codigos.InsertAllOnSubmit(MyCodigo_List);
            dbContab.SubmitChanges();
        }
        catch (Exception ex)
        {
            dbContab = null;

            // ---------------------------------------------
            // escribimos el error al xml file y terminamos

            XElement xml = XElement.Load(filePath);

            xml.Element("Values").Element("Error").ReplaceAll(
                new XElement("ErrorFlag", "1"),
                new XElement("ErrorMessage", ex.Message));

            xml.Save(filePath);

            // para indicar que al progress bar que el proceso terminó
            Session["Progress_Completed"] = 1;

            return;
        }

        // -----------------------------------------------------------------------------------------------
        // ahora copiamos las cuentas contables asociadas a códigos de presupuesto. Nótese que chequeamos
        // que la cuenta contable exista para la compañía, antes de intentar grabarla en la tabla

        // para mostrar el progreso del progreso en la página

        nRegistroActual     = 0;
        nProgressPercentaje = 0;

        nCantidadRegistros = (from cc in dbContab.Presupuesto_AsociacionCodigosCuentas
                              where cc.CiaContab == int.Parse(SourceCiaContab_ListBox.SelectedValue)
                              select cc).Count();

        var AsociacionCodigosCuentas = from acc in dbContab.Presupuesto_AsociacionCodigosCuentas
                                       where acc.CiaContab == int.Parse(SourceCiaContab_ListBox.SelectedValue)
                                       select new { acc.CodigoPresupuesto, acc.CuentaContableID, acc.CuentasContable.Cuenta };

        Presupuesto_AsociacionCodigosCuenta        MyPresupuesto_AsociacionCodigosCuentas;
        List <Presupuesto_AsociacionCodigosCuenta> MyPresupuesto_AsociacionCodigosCuentas_List =
            new List <Presupuesto_AsociacionCodigosCuenta>();

        int nCantidadCuentasContablesAsociadasCopiadas   = 0;
        int nCantidadCuentasContablesAsociadasNoCopiadas = 0;

        foreach (var CuentaContable in AsociacionCodigosCuentas)
        {
            // primero nos aseguramos que la cuenta contable existe en la compañía Target

            // NOTA: como la cuenta contable en el código de presupuesto es el ID de la cuenta, debemos buscar la cuenta (ie: 1001200) para el ID (1500) ...

            CuentasContable cuentaContableEnTargetCia = dbContab.CuentasContables.
                                                        Where(c => c.Cuenta == CuentaContable.Cuenta && c.Cia == int.Parse(TargetCiaContab_ListBox.SelectedValue)).FirstOrDefault();

            if (cuentaContableEnTargetCia == null)
            {
                nCantidadCuentasContablesAsociadasNoCopiadas++;
            }
            else
            {
                MyPresupuesto_AsociacionCodigosCuentas = new Presupuesto_AsociacionCodigosCuenta();

                MyPresupuesto_AsociacionCodigosCuentas.CodigoPresupuesto = CuentaContable.CodigoPresupuesto;
                MyPresupuesto_AsociacionCodigosCuentas.CuentaContableID  = cuentaContableEnTargetCia.ID;
                MyPresupuesto_AsociacionCodigosCuentas.CiaContab         = int.Parse(TargetCiaContab_ListBox.SelectedValue);

                MyPresupuesto_AsociacionCodigosCuentas_List.Add(MyPresupuesto_AsociacionCodigosCuentas);

                nCantidadCuentasContablesAsociadasCopiadas++;
            }

            // ---------------------------------------------------------------------
            // calculamos el progreso (%); es usado por el progress bar en la página
            nRegistroActual++;
            nProgressPercentaje = nRegistroActual * 100 / nCantidadRegistros;

            Session["Progress_Percentage"] = nProgressPercentaje;
            // ----------------------------------------------------------------------
        }



        try
        {
            dbContab.Presupuesto_AsociacionCodigosCuentas.
            InsertAllOnSubmit(MyPresupuesto_AsociacionCodigosCuentas_List);
            dbContab.SubmitChanges();
        }
        catch (Exception ex)
        {
            dbContab = null;

            // ---------------------------------------------
            // escribimos el error al xml file y terminamos

            XElement xml = XElement.Load(filePath);

            xml.Element("Values").Element("Error").ReplaceAll(
                new XElement("ErrorFlag", "1"),
                new XElement("ErrorMessage", ex.Message));

            xml.Save(filePath);

            // para indicar que al progress bar que el proceso terminó
            Session["Progress_Completed"] = 1;

            return;
        }

        // -----------------------------------------------------------------------------------------------------
        // por último, el usuario pudo haber indicado que desea también pasar los registros de montos estimados
        // desde la compañía Source hacia la Target. Nótese que, de ser así, debe venir el año en al textbox
        // que existe para ello

        int nCantidadRegistrosMontosCopiados = 0;

        if (CopiarMontos_CheckBox.Checked && CopiarMontos_DropDownList.SelectedIndex != -1)
        {
            // para mostrar el progreso del progreso en la página

            nRegistroActual     = 0;
            nProgressPercentaje = 0;

            nCantidadRegistros = (from pm in dbContab.Presupuesto_Montos
                                  where pm.CiaContab ==
                                  int.Parse(SourceCiaContab_ListBox.SelectedValue) &&
                                  pm.Ano == int.Parse(CopiarMontos_DropDownList.SelectedValue)
                                  select pm).Count();

            var query = from pm in dbContab.Presupuesto_Montos
                        where pm.CiaContab == int.Parse(SourceCiaContab_ListBox.SelectedValue) &&
                        pm.Ano == int.Parse(CopiarMontos_DropDownList.SelectedValue)
                        select new
            {
                pm.CodigoPresupuesto,
                pm.Moneda,
                pm.Mes01_Est,
                pm.Mes02_Est,
                pm.Mes03_Est,
                pm.Mes04_Est,
                pm.Mes05_Est,
                pm.Mes06_Est,
                pm.Mes07_Est,
                pm.Mes08_Est,
                pm.Mes09_Est,
                pm.Mes10_Est,
                pm.Mes11_Est,
                pm.Mes12_Est
            };

            Presupuesto_Monto        MyPresupuesto_Montos;
            List <Presupuesto_Monto> MyPresupuesto_Montos_List = new List <Presupuesto_Monto>();

            foreach (var Pres_Montos in query)
            {
                MyPresupuesto_Montos = new Presupuesto_Monto();

                MyPresupuesto_Montos.CodigoPresupuesto = Pres_Montos.CodigoPresupuesto;
                MyPresupuesto_Montos.CiaContab         = int.Parse(TargetCiaContab_ListBox.SelectedValue);
                MyPresupuesto_Montos.Moneda            = Pres_Montos.Moneda;
                MyPresupuesto_Montos.Ano = short.Parse(CopiarMontos_DropDownList.SelectedValue);

                MyPresupuesto_Montos.Mes01_Est = Pres_Montos.Mes01_Est;
                MyPresupuesto_Montos.Mes02_Est = Pres_Montos.Mes02_Est;
                MyPresupuesto_Montos.Mes03_Est = Pres_Montos.Mes03_Est;
                MyPresupuesto_Montos.Mes04_Est = Pres_Montos.Mes04_Est;
                MyPresupuesto_Montos.Mes05_Est = Pres_Montos.Mes05_Est;
                MyPresupuesto_Montos.Mes06_Est = Pres_Montos.Mes06_Est;
                MyPresupuesto_Montos.Mes07_Est = Pres_Montos.Mes07_Est;
                MyPresupuesto_Montos.Mes08_Est = Pres_Montos.Mes08_Est;
                MyPresupuesto_Montos.Mes09_Est = Pres_Montos.Mes09_Est;
                MyPresupuesto_Montos.Mes10_Est = Pres_Montos.Mes10_Est;
                MyPresupuesto_Montos.Mes11_Est = Pres_Montos.Mes11_Est;
                MyPresupuesto_Montos.Mes12_Est = Pres_Montos.Mes12_Est;

                MyPresupuesto_Montos_List.Add(MyPresupuesto_Montos);

                nCantidadRegistrosMontosCopiados++;

                // ---------------------------------------------------------------------
                // calculamos el progreso (%); es usado por el progress bar en la página
                nRegistroActual++;
                nProgressPercentaje = nRegistroActual * 100 / nCantidadRegistros;

                Session["Progress_Percentage"] = nProgressPercentaje;
                // ----------------------------------------------------------------------
            }


            try
            {
                dbContab.Presupuesto_Montos.InsertAllOnSubmit(MyPresupuesto_Montos_List);
                dbContab.SubmitChanges();
            }
            catch (Exception ex)
            {
                dbContab = null;

                // ---------------------------------------------
                // escribimos el error al xml file y terminamos

                XElement xml = XElement.Load(filePath);

                xml.Element("Values").Element("Error").ReplaceAll(
                    new XElement("ErrorFlag", "1"),
                    new XElement("ErrorMessage", ex.Message));

                xml.Save(filePath);

                // para indicar que al progress bar que el proceso terminó
                Session["Progress_Completed"] = 1;

                return;
            }
        }
        dbContab = null;

        // ----------------------------------------------------------------------------------------
        // cuando el proceso termina, escribimos los resultados al xml file

        XElement xmlfile = XElement.Load(filePath);

        xmlfile.Element("Values").ReplaceAll(
            new XElement("CantidadCodigosEliminados", nCantidadCodigosEliminados),
            new XElement("CantidadCodigosCopiados", nCantidadCodigosCopiados),
            new XElement("CantidadCuentasContablesAsociadasCopiadas", nCantidadCuentasContablesAsociadasCopiadas),
            new XElement("CantidadCuentasContablesAsociadasNoCopiadas", nCantidadCuentasContablesAsociadasNoCopiadas),
            new XElement("CantidadRegistrosMontosCopiados", nCantidadRegistrosMontosCopiados),
            new XElement("Error",
                         new XElement("ErrorFlag", 0),
                         new XElement("ErrorMessage", "")));

        xmlfile.Save(filePath);

        // para indicar que al progress bar que el proceso terminó
        Session["Progress_Completed"] = 1;
    }