Пример #1
0
        public void AccessRemoteData(string search, int page, int cia)
        {
            try
            {
                dbContab_Contab_Entities dbContab = new dbContab_Contab_Entities();

                // 1) leemos la página de items seleccionados
                var query =
                    "Select Cuenta as id, Descripcion as text From CuentasContables " +
                    "Where (Cuenta Like '%' + @search + '%' Or Descripcion Like '%' + @search + '%') And TotDet = 'D' And Cia = @cia " +
                    "Order by Cuenta, Descripcion Offset @offset Rows Fetch Next 20 Rows Only";

                var args = new DbParameter[] { new SqlParameter {
                                                   ParameterName = "cia", Value = cia
                                               },
                                               new SqlParameter {
                                                   ParameterName = "search", Value = search
                                               },
                                               new SqlParameter {
                                                   ParameterName = "offset", Value = ((page - 1) * 20)
                                               }, };

                var cuentasContables = dbContab.ExecuteStoreQuery <Select2DTO>(query, args).ToList();

                // 2) leemos la cantidad de registros que corresonden a la selección
                query =
                    "Select Count(*) as count_filtered From CuentasContables " +
                    "Where (Cuenta Like '%' + @search + '%' Or Descripcion Like '%' + @search + '%') And TotDet = 'D' And Cia = @cia ";

                args = new DbParameter[] { new SqlParameter {
                                               ParameterName = "cia", Value = cia
                                           },
                                           new SqlParameter {
                                               ParameterName = "search", Value = search
                                           } };

                Int32 count_filtered = dbContab.ExecuteStoreQuery <int>(query, args).First();

                var r = new Select2DTO_paginate {
                    items        = cuentasContables,
                    resultParams = new Select2DTO_paginate_results {
                        page = page, count_filtered = count_filtered
                    }
                };



                JavaScriptSerializer js = new JavaScriptSerializer();
                var sResult             = js.Serialize(r);

                Context.Response.Write(sResult);
            }
            catch (Exception ex)
            {
                Context.Response.Write(ex.Message.ToString());
            }
        }
        private void contabilidad_asientosAjuste(dbContab_Contab_Entities context, int cuentaContableID, int moneda, short ano, int ciaSeleccionada, out bool error, out string message)
        {
            error   = false;
            message = "";

            // asientos
            string queryString =
                $"Select d.NumeroAutomatico as numeroAutomatico, Sum(d.Debe) as sumOfDebe, Sum(d.Haber) as sumOfHaber, " +
                "Sum(d.Debe) - Sum(d.Haber) as diferencia, Max(d.Partida) as ultimaPartida " +
                "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 <asiento_sumarizacion> query = context.ExecuteStoreQuery <asiento_sumarizacion>(queryString, ano, moneda, ciaSeleccionada).ToList();
            dAsiento partida;

            int asientosContablesAjustados = 0;

            foreach (asiento_sumarizacion p in query)
            {
                partida = new dAsiento();

                partida.NumeroAutomatico = p.numeroAutomatico;
                partida.Partida          = Convert.ToInt16(p.ultimaPartida + 10);
                partida.CuentaContableID = cuentaContableID;
                partida.Descripcion      = "Reconversión (2018) - ajuste al asiento contable";
                partida.Referencia       = null;
                partida.Debe             = p.diferencia <= 0 ? Math.Abs(p.diferencia) : 0;
                partida.Haber            = p.diferencia > 0 ? Math.Abs(p.diferencia) : 0;

                context.dAsientos.AddObject(partida);
                asientosContablesAjustados++;
            }

            try
            {
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                error   = true;
                message = "Ha ocurrido un error al intentar ejecutar una operación de acceso a la base de datos. <br /> " +
                          "El mensaje específico de error es: " + ex.Message + "<br /><br />";

                context.Dispose();

                return;
            }

            context.Dispose();

            message = $"<h3>Asientos contables - ajuste contra cuenta de reconversión</h3><br />" +
                      $"Ok, El proceso ha finalizado en forma satisfactoria.<br /><br />" +
                      $"En total, se han actualizado: {asientosContablesAjustados.ToString()} asientos contables, para ajustarlos y <em>cuadrarlos</em> a cero. ";

            return;
        }
        private void CrearInfoReport(out string errorMessage)
        {
            errorMessage = "";

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

            string usuario = User.Identity.Name;

            if (Session["BalanceGeneral_Parametros"] == null)
            {
                errorMessage = "Aparentemente, Ud. no ha definido un filtro para esta consulta. Por favor defina un filtro para esta consulta antes de continuar.";
                return;
            }

            BalanceGeneral_Parametros parametros = Session["BalanceGeneral_Parametros"] as BalanceGeneral_Parametros;

            // --------------------------------------------------------------------------------------------------------------------------------
            // determinamos si el mes que corresponde al inicio del período está cerrado; debe estarlo para que la información regresada por esta
            // consulta sea confiable; de no ser así, indicamos pero permitimos continuar ...

            // nótese como usamos un modelo de datos LinqToSql (no EF), pues el código en la clase AsientosContables lo usa así y fue
            // escrito hace bastante tiempo ...
            //ContabSysNet_Web.ModelosDatos.dbContabDataContext contabLinqToSqlContex = new ContabSysNet_Web.ModelosDatos.dbContabDataContext();

            dbContab_Contab_Entities dbContab = new dbContab_Contab_Entities();

            //FuncionesContab funcionesContab = new FuncionesContab(parametros.CiaContab, parametros.Moneda, contabLinqToSqlContex);
            FuncionesContab2 funcionesContab2 = new FuncionesContab2(dbContab);

            bool   mesAnteriorCerradoEnContab = true;
            string popupMessage = "";

            short mesFiscal;
            short anoFiscal;

            // el mes *anterior* al período de la consulta debe estar cerrado. La función regresa False cuando el mes está cerrado
            // por eso fallamos si el mes *anterior* no está cerrado; es decir, cuando la función regresa True ...
            if (funcionesContab2.ValidarMesCerradoEnContab(parametros.Desde.AddMonths(-1), parametros.CiaContab, out mesFiscal, out anoFiscal, out errorMessage))
            {
                // NOTA: el mes *anterior* a la fecha de inicio DEBE estar cerrado (o uno posterior)
                // la función regresa False si el mes está cerrado
                // si la función regresa True es que NO está cerrado y eso no debe ocurrir en este contexto
                popupMessage = "El mes anterior al mes indicado para esta consulta, <b>no</b> está cerrado. <br /> " +
                               "Aunque Ud. puede continuar e intentar obtener esta consulta, las cifras determinadas y " +
                               "mostradas no serán del todo confiables.<br /><br />" +
                               "Aún así, desea continuar con la ejecución de esta consulta?";

                mesAnteriorCerradoEnContab = false;
            }

            ParametrosContab parametrosContab = dbContab.ParametrosContabs.Where(p => p.Cia == parametros.CiaContab).FirstOrDefault();

            if (parametrosContab == null)
            {
                errorMessage = "Aparentemente, la tabla de parámetros (Contab) no ha sido inicializada. " +
                               "Por favor inicialize esta tabla con los valores que sean adecuados, para la Cia Contab seleccionada para esta consulta.";

                return;
            }

            // ----------------------------------------------------------------------------------------------------------------------------
            // construimos el filtro de las cuentas contables, en base al contenido de la tabla ParametrosContab; en esta tabla el usuario indica
            // cuales cuentas contables corresponden a: activo, pasivo, capital, etc. Para BG, solo cuentas reales son leídas; para GyP solo cuentas
            // nominales son leídas ...
            string filtroBalGen_GyP = "";

            ConstruirFiltroBalGenGyP(parametros, parametrosContab, dbContab, out filtroBalGen_GyP);

            string filtroConsulta = parametros.Filtro + filtroBalGen_GyP;

            // ----------------------------------------------------------------------------------------------------------------------------
            // hacemos una validación: intentamos encontrar cuentas contables de tipo detalle, que tengan movimientos en el período indicado, pero que no tengan
            // un registro de saldos; estos casos pueden ocurrir para cuentas contables recién agregadas, a la cuales se le han agregado asientos pero que aún
            // no se ha ejecutado un cierre mensual que agregue un registro de saldos para éstas. Notificamos esta situación al usuario para que ejecute un
            // cierre mensual que agregue un registro de saldos para estas cuentas ...

            DateTime fecha1erDiaMes = new DateTime(parametros.Desde.Year, parametros.Desde.Month, 1);

            // nótese como no aplicamos el filtro específico a esta consulta, pues resulta complicado. Sin embargo, al no hacerlo, validamos
            // esta situación para todas las cuentas de la compañía, en vez de solo para las que cumplen el filtro ...
            string commandString = "Select c.Cuenta As CuentaContable, c.Descripcion " +
                                   "From CuentasContables c Inner Join dAsientos d On c.ID = d.CuentaContableID " +
                                   "Inner Join Asientos a On d.NumeroAutomatico = a.NumeroAutomatico " +
                                   "Where c.Cia = {2} And c.TotDet = 'D' And " +
                                   "a.Fecha Between {0} And {1} " +
                                   "And c.ID Not In (Select s.CuentaContableID From SaldosContables s Where " +
                                   "s.Cia = {2})";

            CuentaContableItem cuentasTipoDetalleSinRegistroDeSaldos = dbContab.ExecuteStoreQuery <CuentaContableItem>(commandString,
                                                                                                                       fecha1erDiaMes.ToString("yyyy-MM-dd"),
                                                                                                                       parametros.Hasta.ToString("yyyy-MM-dd"),
                                                                                                                       parametros.CiaContab).
                                                                       FirstOrDefault();

            if (cuentasTipoDetalleSinRegistroDeSaldos != null)
            {
                errorMessage = "Hemos encontrado que existen cuentas contables, por ejemplo <b><en>" +
                               (cuentasTipoDetalleSinRegistroDeSaldos.CuentaContable != null ? cuentasTipoDetalleSinRegistroDeSaldos.CuentaContable.Trim() :
                                "'cuenta contable sin número asignado - número en blanco'") +
                               " - " +
                               (cuentasTipoDetalleSinRegistroDeSaldos.Descripcion != null ? cuentasTipoDetalleSinRegistroDeSaldos.Descripcion.Trim() :
                                "'cuenta contable sin descripción asignada - descripción en blanco'") +
                               "</en></b>, con asientos registrados en el período indicado, pero sin un registro de saldos contables." +
                               "Lo más probable es que estas cuentas sean nuevas y hayan recibido asientos; sin embargo, como el cierre contable (mensual) " +
                               "no se ha corrido, su registro de saldos contables no ha sido creado aún. " +
                               "Por favor ejecute un cierre contable para el mes de la consulta para que se corrija esta situación.";

                return;
            }

            // ----------------------------------------------------------------------------------------------------------------------------
            // por último, determinamos si existen cuentas contables de tipo total y que tengan movimientos contables asociados para el período indicado.
            // esta situación puede ocurrir si el usuario cambia el tipo de una cuenta de detalle a total, para una cuenta que tenga asientos (el registro de
            // cuentas no debe permitir este cambio!). Notificamos esta situación al usuario y detenemos la ejecución del proceso ...

            // nótese como buscamos aquí sin usar el filtro que aplica a esta consulta; esto nos permite reportar esta situación tan grave,
            // independientemente del filtro que haya indicado el usuario ...
            commandString = "Select c.Cuenta As CuentaContable, c.Descripcion " +
                            "From CuentasContables c Inner Join dAsientos d On c.ID = d.CuentaContableID " +
                            "Inner Join Asientos a On d.NumeroAutomatico = a.NumeroAutomatico " +
                            "Where c.Cia = {0} And c.TotDet = 'T' And a.Fecha Between {1} And {2}";

            CuentaContableItem cuentasTipoTotalConMovimientos = dbContab.ExecuteStoreQuery <CuentaContableItem>(commandString,
                                                                                                                parametros.CiaContab,
                                                                                                                fecha1erDiaMes.ToString("yyyy-MM-dd"),
                                                                                                                parametros.Hasta.ToString("yyyy-MM-dd")).
                                                                FirstOrDefault();

            if (cuentasTipoTotalConMovimientos != null)
            {
                errorMessage = "Hemos encontrado que existen cuentas contables de tipo total, por ejemplo '<b><en>" +
                               (cuentasTipoTotalConMovimientos.CuentaContable != null ? cuentasTipoTotalConMovimientos.CuentaContable.Trim() :
                                "'cuenta contable sin número asignado - número en blanco'") +
                               " - " +
                               (cuentasTipoTotalConMovimientos.Descripcion != null ? cuentasTipoTotalConMovimientos.Descripcion.Trim() :
                                "'cuenta contable sin descripción asignada - descripción en blanco'") +
                               "</en></b>', con asientos registrados en el período indicado. " +
                               "Una cuenta contable de tipo total no puede recibir asientos contables. " +
                               "Por favor revise y corrija esta situación. Luego regrese a continuar con este proceso.";

                return;
            }

            if (!mesAnteriorCerradoEnContab)
            {
                // arriba, se determinó que el mes anterior al mes indicado no esta cerrado en Contab; de ser así, esta consulta no podrá determinar
                // lo saldos iniciales del período (saldos finales del mes anterior) de una manera confiable; sin embargo, notificamos al usaurio y
                // permitimos continuar (o no!) ...

                // nótese que si el usuario decide continuar, el metodo btnOk_Click es ejecutado; si el usuario cancela, simplemente la ejecución del
                // proceso es detenida en el cliente (browser) ...

                this.ModalPopupTitle_span.InnerHtml = "El mes contable que corresponde a los saldos iniciales del período indicado no está cerrado";
                this.ModalPopupBody_span.InnerHtml  = popupMessage;

                this.btnOk.Visible  = true;
                this.btnCancel.Text = "Cancelar";

                this.ModalPopupExtender1.Show();

                return;
            }

            // las validaciones pasaron; ejecutamos la función que prepara y la consulta ...
            ConstruirConsulta(out errorMessage);
        }
        private void contabilidad_saldosInicialesCuadrar(dbContab_Contab_Entities context, int cuentaContableID, int moneda, short ano, int ciaSeleccionada, out bool error, out string message)
        {
            error   = false;
            message = "";

            // asientos
            string queryString =
                $"Select s.Moneda as moneda, s.MonedaOriginal as monedaOriginal, s.Ano as ano, s.Cia as cia, Sum(s.Inicial) as sumOfInicial " +
                "From SaldosContables s Inner Join CuentasContables c On s.CuentaContableID = c.ID " +
                "Where s.Ano = {0} And s.Moneda = {1} And s.Cia = {2} " +
                "And c.TotDet = 'D' " +
                "Group By s.Moneda, s.MonedaOriginal, s.Ano, s.Cia";

            List <saldos_sumarizacion> query = context.ExecuteStoreQuery <saldos_sumarizacion>(queryString, ano, moneda, ciaSeleccionada).ToList();
            SaldosContable             saldoContable;

            int saldosContables_ajustados = 0;
            int saldosContables_agregados = 0;

            foreach (saldos_sumarizacion inicial in query)
            {
                if (inicial.sumOfInicial == 0)
                {
                    // si no hay diferencia en el saldo inicial, simplemente continuamos ...
                    continue;
                }


                // leemos un registro de saldos para la cuenta contable, a ver si existe
                saldoContable = context.SaldosContables.Where(s => s.CuentaContableID == cuentaContableID &&
                                                              s.Moneda == inicial.moneda && s.MonedaOriginal == inicial.monedaOriginal &&
                                                              s.Ano == inicial.ano && s.Cia == inicial.cia).FirstOrDefault();

                if (saldoContable != null)
                {
                    // el registro de saldos para la: cuenta, moneda y moneda  original *existe*; lo actualizamos

                    // calculamos el nuevo saldo inicial (ajustado)
                    decimal nuevoInicial = saldoContable.Inicial.HasValue ? saldoContable.Inicial.Value : 0;

                    if (inicial.sumOfInicial >= 0)
                    {
                        nuevoInicial = nuevoInicial - inicial.sumOfInicial;                     // la diferencia es mayor que cero; para ajustar, restamos
                    }
                    else
                    {
                        nuevoInicial = nuevoInicial + Math.Abs(inicial.sumOfInicial);           // la diferencia es menor que cero; para ajustar, sumamos
                    }
                    saldoContable.Inicial = nuevoInicial;
                    saldosContables_ajustados++;
                }
                else
                {
                    // el registro de saldos para la cuenta *no existe*; lo agregamos

                    SaldosContable saldo = new SaldosContable
                    {
                        CuentaContableID = cuentaContableID,
                        Moneda           = inicial.moneda,
                        MonedaOriginal   = inicial.monedaOriginal,
                        Ano = inicial.ano,
                        // agregamos la diferencia, justo con el signo contrario ...
                        Inicial = (inicial.sumOfInicial * -1),
                        Mes01   = 0,
                        Mes02   = 0,
                        Mes03   = 0,
                        Mes04   = 0,
                        Mes05   = 0,
                        Mes06   = 0,
                        Mes07   = 0,
                        Mes08   = 0,
                        Mes09   = 0,
                        Mes10   = 0,
                        Mes11   = 0,
                        Mes12   = 0,
                        Anual   = 0,
                        Cia     = inicial.cia,
                    };

                    saldosContables_agregados++;
                    context.SaldosContables.AddObject(saldo);
                }
            }


            try
            {
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                error   = true;
                message = $"<h3>Saldos iniciales - Cuadre contra cuenta de reconversión</h3><br />" +
                          "Ha ocurrido un error al intentar ejecutar una operación de acceso a la base de datos. <br /> " +
                          "El mensaje específico de error es: " + ex.Message + "<br /><br />";

                context.Dispose();

                return;
            }

            context.Dispose();

            message = $"<h3>Saldos iniciales - ajuste contra cuenta de reconversión</h3><br />" +
                      $"Ok, El proceso ha finalizado en forma satisfactoria.<br /><br />" +
                      $"En total, se han <b>actualizado</b>: {saldosContables_ajustados.ToString()} registros de saldo, para ajustar el saldo inicial del año y <em>cuadrarlo</em> a cero.<br />" +
                      $"Además, se han <b>agregado</b>: {saldosContables_agregados.ToString()} registros de saldo, para ajustar el saldo inicial del año y <em>cuadrarlo</em> a cero.";

            return;
        }
        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 RefreshAndBindInfo()
        {
            if (!User.Identity.IsAuthenticated)
            {
                FormsAuthentication.SignOut();
                return;
            }

            if (Session["filtroForma_consultaAsientosContables"] == null)
            {
                ErrMessage_Span.InnerHtml = "Aparentemente, Ud. no ha indicado un filtro aún.<br />Por favor indique y aplique un filtro " +
                                            "antes de intentar mostrar el resultado de la consulta.";
                ErrMessage_Span.Style["display"] = "block";

                return;
            }

            // --------------------------------------------------------------------------------------------
            // determinamos el mes y año fiscales, para usarlos como criterio para buscar el saldo en la tabla
            // SaldosContables. En esta table, los saldos están para el mes fiscal y no para el mes calendario.
            // Los meses solo varían cuando el año fiscal no es igual al año calendario

            // --------------------------------------------------------------------------------------------
            // eliminamos el contenido de la tabla temporal

            dbContab_Contab_Entities context = new dbContab_Contab_Entities();

            try
            {
                context.ExecuteStoreCommand("Delete From tTempWebReport_ConsultaComprobantesContables Where NombreUsuario = {0}", Membership.GetUser().UserName);
            }
            catch (Exception ex)
            {
                context.Dispose();

                ErrMessage_Span.InnerHtml = "Ha ocurrido un error al intentar ejecutar una operación de acceso a la base de datos. <br /> " +
                                            "El mensaje específico de error es: " + ex.Message + "<br /><br />";
                ErrMessage_Span.Style["display"] = "block";

                return;
            }

            // ----------------------------------------------------------------------------------------------------------------------
            // leemos la tabla de monedas para 'saber' cual es la moneda Bs. Nota: la idea es aplicar las opciones de reconversión
            // *solo* a esta moneda
            var monedaNacional_return = Reconversion.Get_MonedaNacional();

            if (monedaNacional_return.error)
            {
                ErrMessage_Span.InnerHtml        = monedaNacional_return.message;
                ErrMessage_Span.Style["display"] = "block";

                return;
            }

            Monedas monedaNacional = monedaNacional_return.moneda;
            // ----------------------------------------------------------------------------------------------------------------------

            // agregamos este flag luego de la reconversión del 1-Oct-21
            // la idea es que el usuario pueda decidir si reconvertir montos
            bool bReconvertirCifrasAntes_01Oct2021 = (bool)Session["ReconvertirCifrasAntes_01Oct2021"];

            // el usuario puede indicar que desea *solo* asientos con uploads
            string joinTableAsientosUploads = "Left Outer Join ";

            if (Session["SoloAsientosConUploads_CheckBox"] != null && Convert.ToBoolean(Session["SoloAsientosConUploads_CheckBox"]))
            {
                joinTableAsientosUploads = "Join ";
            }

            // usamos el criterio que indico el usuario para leer las cuentas contables y grabarlas a una tabla en la base de datos temporal

            // NOTA: *solo* si el usuario usa algunos criterios en el filtro, usamos un subquery en el select a los asientos contables

            // nótese que el select a la tabla de links (asientos_documentos_links) se hace en un subquery; la idea es evitar que los counts se multipliquen
            // por la cantidad de registros en el primer join. cuando en sql se hacen counts, sum, etc., y hay más de dos tablas en el select, los montos
            // se desvirtúan. La solución es usar subqueries para las tablas que siguen a la segunda ...
            string sSqlQueryString = "";

            if (Session["filtroForma_consultaAsientosContables_subQuery"] == null || Session["filtroForma_consultaAsientosContables_subQuery"].ToString() == "1 = 1")
            {
                sSqlQueryString = "SELECT Asientos.NumeroAutomatico, Asientos.Moneda, Asientos.Fecha, " +
                                  "Count(dAsientos.Partida) As NumPartidas, Sum(dAsientos.Debe) As TotalDebe, Sum(dAsientos.Haber) AS TotalHaber, " +
                                  "iif(links.NumLinks Is Not Null, links.NumLinks, 0) As NumLinks, Lote As Lote " +
                                  "FROM Asientos Left Outer Join dAsientos On Asientos.NumeroAutomatico = dAsientos.NumeroAutomatico " +
                                  joinTableAsientosUploads +    // 'join' o 'left join' dependiendo de si el usuario quiere *solo* asientos con uploads
                                  "(SELECT Asientos_Documentos_Links.NumeroAutomatico, Count(Asientos_Documentos_Links.Id) as NumLinks " +
                                  "FROM Asientos_Documentos_Links " +
                                  "Group By Asientos_Documentos_Links.NumeroAutomatico) as links On Asientos.NumeroAutomatico = links.NumeroAutomatico " +
                                  "Where " + Session["filtroForma_consultaAsientosContables"].ToString() + " " +
                                  "Group By Asientos.NumeroAutomatico, Asientos.Moneda, Asientos.Fecha, Asientos.Lote, links.NumLinks";
            }
            else
            {
                // usamos un subquery para que solo asientos con ciertas cuentas *o* partidas con montos con más de 2 decimales sean seleccionados
                sSqlQueryString = "SELECT Asientos.NumeroAutomatico, Asientos.Moneda, Asientos.Fecha, " +
                                  "Count(dAsientos.Partida) As NumPartidas, Sum(dAsientos.Debe) As TotalDebe, Sum(dAsientos.Haber) AS TotalHaber, " +
                                  "iif(links.NumLinks Is Not Null, links.NumLinks, 0) As NumLinks, Lote As Lote " +
                                  "FROM Asientos " +
                                  "Left Outer Join dAsientos On Asientos.NumeroAutomatico = dAsientos.NumeroAutomatico " +
                                  "Left Outer Join CuentasContables On CuentasContables.ID = dAsientos.CuentaContableID " +

                                  joinTableAsientosUploads +    // 'join' o 'left join' dependiendo de si el usuario quiere *solo* asientos con uploads
                                  "(SELECT Asientos_Documentos_Links.NumeroAutomatico, Count(Asientos_Documentos_Links.Id) as NumLinks " +
                                  "FROM Asientos_Documentos_Links " +
                                  "Group By Asientos_Documentos_Links.NumeroAutomatico) as links On Asientos.NumeroAutomatico = links.NumeroAutomatico " +

                                  "Where " + Session["filtroForma_consultaAsientosContables"].ToString() +
                                  " And (Asientos.NumeroAutomatico In (SELECT Asientos.NumeroAutomatico FROM Asientos " +
                                  "Left Outer Join dAsientos On Asientos.NumeroAutomatico = dAsientos.NumeroAutomatico " +
                                  "Left Outer Join CuentasContables On CuentasContables.ID = dAsientos.CuentaContableID " +
                                  "Where " + Session["filtroForma_consultaAsientosContables"].ToString() + " And " +
                                  Session["filtroForma_consultaAsientosContables_subQuery"].ToString() + "))" +
                                  "Group By Asientos.NumeroAutomatico, Asientos.Moneda, Asientos.Fecha, Asientos.Lote, links.NumLinks";
            }

            if (Session["SoloAsientosDescuadrados"] != null && Convert.ToBoolean(Session["SoloAsientosDescuadrados"]))
            {
                sSqlQueryString = sSqlQueryString + " Having Sum(dAsientos.Debe) <> Sum(dAsientos.Haber)";
            }


            List <ComprobanteContable_Object>            query = context.ExecuteStoreQuery <ComprobanteContable_Object>(sSqlQueryString).ToList();
            tTempWebReport_ConsultaComprobantesContables MyComprobantesContable;

            decimal nTotalDebe        = 0;
            decimal nTotalHaber       = 0;
            int     cantidadRegistros = 0;

            DateTime fechaReconversion2021 = new DateTime(2021, 10, 1);

            foreach (ComprobanteContable_Object a in query)
            {
                decimal totalDebe  = a.TotalDebe != null ? a.TotalDebe.Value : 0;
                decimal totalHaber = a.TotalHaber != null ? a.TotalHaber.Value : 0;
                // -----------------------------------------------------------------------------------------
                // el usuario puede indicar que quiere reconvertir cifras anteriores al 31/Oct/21
                if (bReconvertirCifrasAntes_01Oct2021 && (a.Moneda == monedaNacional.Moneda) && (a.Fecha < fechaReconversion2021))
                {
                    totalDebe /= 1000000;
                    totalDebe  = Math.Round(totalDebe, 2);

                    totalHaber /= 1000000;
                    totalHaber  = Math.Round(totalHaber, 2);
                }

                MyComprobantesContable = new tTempWebReport_ConsultaComprobantesContables();

                MyComprobantesContable.NumeroAutomatico = a.NumeroAutomatico;
                MyComprobantesContable.NumPartidas      = Convert.ToInt16(a.NumPartidas);
                MyComprobantesContable.TotalDebe        = totalDebe;
                MyComprobantesContable.TotalHaber       = totalHaber;
                MyComprobantesContable.NombreUsuario    = Membership.GetUser().UserName;
                MyComprobantesContable.NumUploads       = Convert.ToInt16(a.NumLinks);
                MyComprobantesContable.Lote             = a.Lote;

                context.tTempWebReport_ConsultaComprobantesContables.AddObject(MyComprobantesContable);

                nTotalDebe  += totalDebe;
                nTotalHaber += totalHaber;
                cantidadRegistros++;
            }

            try
            {
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                string errorMessage = ex.Message;
                if (ex.InnerException != null)
                {
                    errorMessage += "<br />" + ex.InnerException.Message;
                }
                ErrMessage_Span.InnerHtml = "Ha ocurrido un error al intentar ejecutar una operación de acceso a la base de datos. <br /> " +
                                            "El mensaje específico de error es: " +
                                            errorMessage;
                ErrMessage_Span.Style["display"] = "block";

                context.Dispose();
                return;
            }

            context.Dispose();

            this.CompaniasFilter_DropDownList.DataBind();
            this.MonedasFilter_DropDownList.DataBind();
            ComprobantesContables_ListView.DataBind();

            // actualizamos los totales en el footer en el ListView
            Label numberOfRecords_label = (Label)ComprobantesContables_ListView.FindControl("numberOfRecords_label");
            Label MySumOfDebe_Label     = (Label)ComprobantesContables_ListView.FindControl("SumOfDebe_Label");
            Label MySumOfHaber_Label    = (Label)ComprobantesContables_ListView.FindControl("SumOfHaber_Label");

            if (numberOfRecords_label != null)
            {
                numberOfRecords_label.Text = cantidadRegistros.ToString();
            }

            if (MySumOfDebe_Label != null)
            {
                MySumOfDebe_Label.Text = nTotalDebe.ToString("#,##0.000");
            }

            if (MySumOfHaber_Label != null)
            {
                MySumOfHaber_Label.Text = nTotalHaber.ToString("#,##0.000");
            }
        }
        private void RefreshAndBindInfo()
        {
            if (this.User != null && this.User.Identity != null && !User.Identity.IsAuthenticated)
            {
                FormsAuthentication.SignOut();
                return;
            }

            if (Session["FiltroForma"] == null)
            {
                Session["Thread_ErrorMessage"] = "Aparentemente, Ud. no ha indicado un filtro aún.<br /> " +
                                                 "Por favor indique y aplique un filtro antes de intentar mostrar el resultado de " +
                                                 "la consulta.";
                return;
            }

            Session["Progress_Percentage"] = 0;
            string errorMessage = "";

            // nota importante: esta consulta (y otras?) deben, al menos por ahora, ser pedidas para una CiaContab
            // en particular, pues los años fiscales para las Cias Contab pueden variar entre ellas ...
            if (Session["CiaContabSeleccionada"] == null)
            {
                // el usuario debe seleccionar una cia contab en particular, pues los saldos contables se leen
                // de acuerdo al año fiscal de la misma ...

                Session["Thread_ErrorMessage"] = "Aparentemente, no se ha seleccionado una Cia Contab.<br /> " +
                                                 "Por favor seleccione una Cia Contab al establecer el filtro a usar para esta consulta.";

                Session["Progress_SelectedRecs"] = 0;
                Session["Progress_Completed"]    = 1;
                Session["Progress_Percentage"]   = 0;

                return;
            }

            var ciaContabSeleccionada = Convert.ToInt32(Session["CiaContabSeleccionada"].ToString());

            var dFechaInicialPeriodoIndicado = (System.DateTime)Session["FechaInicialPeriodo"];
            var dFechaFinalPeriodoIndicado   = (System.DateTime)Session["FechaFinalPeriodo"];

            bool bReconvertirCifrasAntes_01Oct2021      = (bool)Session["ReconvertirCifrasAntes_01Oct2021"];
            bool bExcluirAsientosReconversion_01Oct2021 = (bool)Session["ExcluirAsientosReconversion_01Oct2021"];

            bool bExcluirAsientosTipoCierreAnual = (bool)Session["ExcluirAsientosTipoCierreAnual"];

            // ----------------------------------------------------------------------------------------------------------------------
            // leemos la tabla de monedas para 'saber' cual es la moneda Bs. Nota: la idea es aplicar las opciones de reconversión
            // *solo* a esta moneda
            var monedaNacional_return = Reconversion.Get_MonedaNacional();

            if (monedaNacional_return.error)
            {
                ErrMessage_Span.InnerHtml        = monedaNacional_return.message;
                ErrMessage_Span.Style["display"] = "block";

                return;
            }

            Monedas monedaNacional = monedaNacional_return.moneda;

            Session["monedaNacional"] = monedaNacional.Moneda;
            // ----------------------------------------------------------------------------------------------------------------------

            // --------------------------------------------------------------------------------------------
            // eliminamos el contenido de la tabla temporal
            dbContab_Contab_Entities dbContext = new dbContab_Contab_Entities();

            try
            {
                int cantRegistrosEliminados = dbContext.ExecuteStoreCommand("Delete From Contab_BalanceComprobacion Where NombreUsuario = {0}", Membership.GetUser().UserName);
            }
            catch (Exception ex) {
                dbContext.Dispose();

                Session["Thread_ErrorMessage"] = "Ha ocurrido un error al intentar ejecutar una operación de " +
                                                 "acceso a la base de datos. <br /> El mensaje específico de error es: " + ex.Message +
                                                 "<br /><br />";
                return;
            }

            // -----------------------------------------------------------------------------------------------
            // para evitar que el reporte se genere en forma incompleta, intentamos buscar cuentas que tengan
            // asientos, más no registros en SaldosContables. De haberlas, lo notificamos al usuario y le
            // indicamos que ejecute un cierre contable para corregir esta situación

            string filtroFormParaAsientos = Session["FiltroForma"].ToString();

            filtroFormParaAsientos = filtroFormParaAsientos.Replace("SaldosContables", "Asientos");

            string filtroFormaParaSaldosContables = Session["FiltroForma"].ToString();

            string sSqlQueryString = "Select dAsientos.CuentaContableID From dAsientos " +
                                     "Inner Join Asientos On dAsientos.NumeroAutomatico = Asientos.NumeroAutomatico " +
                                     "Inner Join CuentasContables On dAsientos.CuentaContableID = CuentasContables.ID " +
                                     "Where Asientos.Fecha Between '" + dFechaInicialPeriodoIndicado.ToString("yyyy-MM-dd") + "' And '" +
                                     dFechaFinalPeriodoIndicado.ToString("yyyy-MM-dd") + "' And " +
                                     filtroFormParaAsientos +
                                     " And dAsientos.CuentaContableID Not In " +
                                     "(Select CuentaContableID From SaldosContables Inner Join CuentasContables On SaldosContables.CuentaContableID = CuentasContables.ID " +
                                     "Where " + filtroFormaParaSaldosContables + ")";

            int nCuentasSinSaldo = dbContext.ExecuteStoreQuery <int>(sSqlQueryString).Count();

            if (nCuentasSinSaldo > 0)
            {
                // hay cuentas contables en asientos que no tienen un registro en SaldosContables; lo notificamos al
                // usuario para que corrija esta situación con un cierre contable
                Session["Thread_ErrorMessage"] = "Existen cuentas contables usadas en asientos contables que no tienen " +
                                                 "un registro en la tabla de saldos. <br /> " +
                                                 "Por favor ejecute un cierre contable para el mes (o los meses) de esta consulta, " +
                                                 "para corregir esta situación (y agregar un registro de saldos a las cuentas contables que no lo tienen).";

                Session["Progress_SelectedRecs"] = 0;
                Session["Progress_Completed"]    = 1;
                Session["Progress_Percentage"]   = 0;

                return;
            }

            // hacemos una validación similar a la anterior, pero esta vez buscando cuentas contables que hayan cambiado de detalle a total
            // recuérdese que solo cuentas de tipo detalle pueden recibir asientos; notificamos ésto al usuario, para que corrija esta
            // situación antes de continuar ...
            sSqlQueryString = "Select CuentasContables.CuentaEditada + ' ' + CuentasContables.Descripcion From dAsientos " +
                              "Inner Join Asientos On dAsientos.NumeroAutomatico = Asientos.NumeroAutomatico " +
                              "Inner Join CuentasContables On dAsientos.CuentaContableID = CuentasContables.ID " +
                              "Where Asientos.Fecha Between '" + dFechaInicialPeriodoIndicado.ToString("yyyy-MM-dd") + "' And '" +
                              dFechaFinalPeriodoIndicado.ToString("yyyy-MM-dd") + "' And " +
                              filtroFormParaAsientos +
                              " And CuentasContables.TotDet <> 'D'";

            List <string> query0 = dbContext.ExecuteStoreQuery <string>(sSqlQueryString).ToList();

            errorMessage = "";

            foreach (string cuentaTipoTotal in query0)
            {
                if (string.IsNullOrEmpty(errorMessage))
                {
                    errorMessage = cuentaTipoTotal;
                }
                else
                {
                    errorMessage += ", " + cuentaTipoTotal;
                }
            }

            if (errorMessage != "")
            {
                Session["Thread_ErrorMessage"] = "Aparentemente, existen cuentas contables que han recibido asientos contables en el período indicado y que " +
                                                 "no son de tipo 'detalle'; <br />deben serlo, pues solo cuentas de tipo 'detalle' pueden recibir asientos. <br /> " +
                                                 "Es probable que una cuenta de tipo 'detalle' y que recibió asientos en el período indicado, fue cambiada a tipo 'total' y mantuvo sus asientos.<br /> " +
                                                 "A continuación mostramos las cuentas que están en este estado y que ha detectado este proceso: " + errorMessage;

                Session["Progress_SelectedRecs"] = 0;
                Session["Progress_Completed"]    = 1;
                Session["Progress_Percentage"]   = 0;

                return;
            }
            ;

            // para leer los saldos, debemos determinar el año fiscal de la Cia Contab; un año calendario puede ser
            // 2013 y el año fiscal 2012. Los saldos contables se registran para el año fiscal. Por esta razón,
            // debemos obtenerlo *antes* de hacer el select que sigue
            GetMesFiscalContable MyGetMesFiscalContable = new GetMesFiscalContable(dFechaInicialPeriodoIndicado, ciaContabSeleccionada);

            string sErrorMessage = "";

            // antes usabamos Linq to Sql en vez de EF ...
            ContabSysNet_Web.ModelosDatos.dbContabDataContext ContabDB = new ContabSysNet_Web.ModelosDatos.dbContabDataContext();
            MyGetMesFiscalContable.dbContabDataContext = ContabDB;

            if (!MyGetMesFiscalContable.DeterminarMesFiscal(ref sErrorMessage))
            {
                ContabDB.Dispose();

                ErrMessage_Span.InnerHtml        = sErrorMessage;
                ErrMessage_Span.Style["display"] = "block";

                return;
            }

            int anoFiscalCiaSeleccionada = MyGetMesFiscalContable.AnoFiscal;

            // ------------------------------------------------------------------------------------------------------------------------------
            // como vamos a usar esta conexión mientras se ejecute el ciclo que viene, la abrimos aquí y la cerramos al final ...
            SqlConnection sqlConnection = new SqlConnection();

            sqlConnection.ConnectionString = ConfigurationManager.ConnectionStrings["dbContabConnectionString"].ConnectionString;
            sqlConnection.Open();

            // -----------------------------------------------------------------------------------------------------
            // usamos esta clase para leer los movimientos (debe, haber) para cada cuenta contable y moneda
            DeterminarMovimientoCuentaContable determinarMovimientoCuentaContable = new DeterminarMovimientoCuentaContable(sqlConnection,
                                                                                                                           bExcluirAsientosTipoCierreAnual,
                                                                                                                           bReconvertirCifrasAntes_01Oct2021,
                                                                                                                           bExcluirAsientosReconversion_01Oct2021,
                                                                                                                           dFechaInicialPeriodoIndicado,
                                                                                                                           dFechaFinalPeriodoIndicado, monedaNacional.Moneda);

            // -----------------------------------------------------------------------------------------------------
            // primero determinamos la cantidad de registros, para mostrar progreso al usuario

            // NOTA IMPORTANTE: usamos el año para leer en la tabla SaldosContables SOLO cuentas/monedas/cias que
            // corresopondan al año indicado. Recuérdese que una cuenta/moneda/cia puede tener MUCHOS registros
            // en SaldosContables, uno para cada año. SIN EMBARGO, deberíamos usar el año fiscal y no el año de
            // la fecha inicial del período (año calendario). Lo hacemos así, sabiendo que muy pocas veces ésto
            // tendrá un efecto importante en el proceso. Creo que bastaría con hacer un cierre contable anual en
            // los casos en que el efecto exista

            // ----------------------------------------------------------------------
            // ahora ejecutamos el query para que regrese los rows uno a uno

            // leemos las cuentas contables y todos sus datos de compañías, grupos, monedas, etc. Nótese que leemos
            // SOLO las que tienen un registro en SaldosContables y para el año de la fecha de inicio. La idea es
            // solo traernos cuentas que tengan un registro en SaldosContables, no leer su saldo, lo cual hacemos
            // más adelante, para cada una, en el loop que sigue

            // nótese como cambiamos el Select que sigue, para eliminar la tabla SaldosContables de la
            // sección Inner Join. La razón es que, a veces, puede ocurrir que una cuenta tiene asientos
            // más no tiene un registro en SaldosContables. Imaginamos que ésto puede ocurrir cuando una
            // cuenta se usa por 1ra. vez y no se ha corrido el cierre contable aún para el mes del reporte.

            // ordenamos por CiaContab para que la lista que resulta de aquí también lo esté

            sSqlQueryString = "Select Distinct CuentasContables.ID As CuentaContableID, CuentasContables.Cuenta As CuentaContable, " +
                              "CuentasContables.Descripcion As NombreCuentaContable, " +
                              "tGruposContables.Grupo As GrupoContable, " +
                              "tGruposContables.Descripcion As NombreGrupoContable, " +
                              "IsNull(tGruposContables.OrdenBalanceGeneral, 0) As GrupoContable_OrdenBalance, " +
                              "CuentasContables.Cia As CiaContab, Companias.NombreCorto As NombreCiaContab, " +
                              "CuentaEditada As CuentaContableEditada, Monedas.Moneda, Monedas.Descripcion As " +
                              "NombreMoneda, " + "Monedas.Simbolo As SimboloMoneda, " +
                              "Case NumNiveles When 2 Then Nivel1 When 3 Then Nivel1 + Nivel2 When 4 Then Nivel1 + " +
                              "Nivel2 + Nivel3 " + "When 5 Then Nivel1 + Nivel2 + Nivel3 + Nivel4 When 6 Then Nivel1 + " +
                              "Nivel2 + Nivel3 + Nivel4 + Nivel5 " +
                              "When 7 Then Nivel1 + Nivel2 + Nivel3 + Nivel4 + Nivel5 + Nivel6 End AS " +
                              "CuentaContable_NivelPrevio, " +
                              "Nivel1, Nivel2, Nivel3, Nivel4, Nivel5, Nivel6, NumNiveles " +
                              "From CuentasContables " +
                              "Inner Join Companias On CuentasContables.Cia = Companias.Numero " +
                              "Inner Join SaldosContables On CuentasContables.ID = SaldosContables.CuentaContableID " +
                              "Inner Join Monedas On SaldosContables.Moneda = Monedas.Moneda " +
                              "Inner Join tGruposContables On CuentasContables.Grupo = tGruposContables.Grupo " +
                              "Where CuentasContables.TotDet = 'D' And SaldosContables.Ano = " +
                              anoFiscalCiaSeleccionada.ToString() +
                              " And " + Session["FiltroForma"].ToString() + " Order by CuentasContables.Cia";

            List <CuentaContable_Object> query = dbContext.ExecuteStoreQuery <CuentaContable_Object>(sSqlQueryString).ToList();

            if (query.Count() == 0)
            {
                Session["Thread_ErrorMessage"] = "No existen registros que cumplan el criterio de selección " +
                                                 "(filtro) que Ud. ha indicado. <br /> Para regresar registros, " +
                                                 "Ud. puede intentar un filtro diferente al que ha indicado.";

                Session["Progress_SelectedRecs"] = 0;
                Session["Progress_Completed"]    = 1;
                Session["Progress_Percentage"]   = 0;

                return;
            }

            // ---------------------------------------------------------------------------------------------
            // variables usadas para mostrar el meter en la página ...
            int nCantidadRegistros = query.Count();

            int nRegistroActual     = 0;
            int nProgreesPercentaje = 0;

            string nombreUsuario = Membership.GetUser().UserName;

            Session["Progress_SelectedRecs"] = 0;
            // ---------------------------------------------------------------------------------------------

            List <BalanceComprobacion_Item> MyBalanceComprobacion_Lista = new List <BalanceComprobacion_Item>();
            BalanceComprobacion_Item        MyBalanceComprobacion_Record;

            foreach (CuentaContable_Object MyComprobanteContable_Query in query)
            {
                MyBalanceComprobacion_Record = new BalanceComprobacion_Item();

                MyBalanceComprobacion_Record.CuentaContableID          = MyComprobanteContable_Query.CuentaContableID;
                MyBalanceComprobacion_Record.Moneda                    = MyComprobanteContable_Query.Moneda;
                MyBalanceComprobacion_Record.NivelPrevioCuentaContable = MyComprobanteContable_Query.CuentaContable_NivelPrevio;
                MyBalanceComprobacion_Record.Cia = MyComprobanteContable_Query.CiaContab;

                // nótese como agregamos todos los niveles 'previos' de la cuenta, para poder totalizar por éstos en el reporte ...
                switch (MyComprobanteContable_Query.NumNiveles)
                {
                case 2:
                    MyBalanceComprobacion_Record.nivel1 = MyComprobanteContable_Query.Nivel1;
                    break;

                case 3:
                    MyBalanceComprobacion_Record.nivel1 = MyComprobanteContable_Query.Nivel1;
                    MyBalanceComprobacion_Record.nivel2 = MyBalanceComprobacion_Record.nivel1 + MyComprobanteContable_Query.Nivel2;
                    break;

                case 4:
                    MyBalanceComprobacion_Record.nivel1 = MyComprobanteContable_Query.Nivel1;
                    MyBalanceComprobacion_Record.nivel2 = MyBalanceComprobacion_Record.nivel1 + MyComprobanteContable_Query.Nivel2;
                    MyBalanceComprobacion_Record.nivel3 = MyBalanceComprobacion_Record.nivel2 + MyComprobanteContable_Query.Nivel3;
                    break;

                case 5:
                    MyBalanceComprobacion_Record.nivel1 = MyComprobanteContable_Query.Nivel1;
                    MyBalanceComprobacion_Record.nivel2 = MyBalanceComprobacion_Record.nivel1 + MyComprobanteContable_Query.Nivel2;
                    MyBalanceComprobacion_Record.nivel3 = MyBalanceComprobacion_Record.nivel2 + MyComprobanteContable_Query.Nivel3;
                    MyBalanceComprobacion_Record.nivel4 = MyBalanceComprobacion_Record.nivel3 + MyComprobanteContable_Query.Nivel4;
                    break;

                case 6:
                    MyBalanceComprobacion_Record.nivel1 = MyComprobanteContable_Query.Nivel1;
                    MyBalanceComprobacion_Record.nivel2 = MyBalanceComprobacion_Record.nivel1 + MyComprobanteContable_Query.Nivel2;
                    MyBalanceComprobacion_Record.nivel3 = MyBalanceComprobacion_Record.nivel2 + MyComprobanteContable_Query.Nivel3;
                    MyBalanceComprobacion_Record.nivel4 = MyBalanceComprobacion_Record.nivel3 + MyComprobanteContable_Query.Nivel4;
                    MyBalanceComprobacion_Record.nivel5 = MyBalanceComprobacion_Record.nivel4 + MyComprobanteContable_Query.Nivel5;
                    break;

                case 7:
                    MyBalanceComprobacion_Record.nivel1 = MyComprobanteContable_Query.Nivel1;
                    MyBalanceComprobacion_Record.nivel2 = MyBalanceComprobacion_Record.nivel1 + MyComprobanteContable_Query.Nivel2;
                    MyBalanceComprobacion_Record.nivel3 = MyBalanceComprobacion_Record.nivel2 + MyComprobanteContable_Query.Nivel3;
                    MyBalanceComprobacion_Record.nivel4 = MyBalanceComprobacion_Record.nivel3 + MyComprobanteContable_Query.Nivel4;
                    MyBalanceComprobacion_Record.nivel5 = MyBalanceComprobacion_Record.nivel4 + MyComprobanteContable_Query.Nivel5;
                    MyBalanceComprobacion_Record.nivel6 = MyBalanceComprobacion_Record.nivel5 + MyComprobanteContable_Query.Nivel6;
                    break;
                }

                MyBalanceComprobacion_Lista.Add(MyBalanceComprobacion_Record);

                // --------------------------------------------------------------------------------------
                // ... para reportar el progreso al usuario; la página ejecuta un ws que lee el valor de
                // estas session variables
                nRegistroActual    += 1;
                nProgreesPercentaje = nRegistroActual * 100 / nCantidadRegistros;

                Session["Progress_Percentage"]   = nProgreesPercentaje;
                Session["Progress_SelectedRecs"] = (int)Session["Progress_SelectedRecs"] + 1;
            }

            // ---------------------------------------------------------------------------------
            // recorremos la lista para determinar saldo anterior, debe, haber y saldo actual

            // -----------------------------------------------------------------
            // determinamos la cantidad de registros para el progress al usuario
            nCantidadRegistros = MyBalanceComprobacion_Lista.Count();
            // -----------------------------------------------------------------

            nRegistroActual = 0;
            Session["Progress_Percentage"] = 0;

            int nCiaContabAnterior = -999999;

            int    nMesFiscal     = 0;
            int    nAnoFiscal     = 0;
            int    nMesCalendario = 0;
            int    nAnoCalendario = 0;
            string sNombreMes     = "";

            System.DateTime dFechaSaldoInicial;

            Session["Progress_SelectedRecs"] = 0;

            foreach (BalanceComprobacion_Item MyBalanceComprobacion_Record2 in MyBalanceComprobacion_Lista.OrderBy(b => b.Cia))
            {
                if (MyBalanceComprobacion_Record2.Cia != nCiaContabAnterior)
                {
                    // buscamos el mes y año fiscal solo cuando cambian las compañías
                    MyGetMesFiscalContable = new GetMesFiscalContable(dFechaInicialPeriodoIndicado, MyBalanceComprobacion_Record2.Cia);

                    sErrorMessage = "";
                    MyGetMesFiscalContable.dbContabDataContext = ContabDB;
                    if (!MyGetMesFiscalContable.DeterminarMesFiscal(ref sErrorMessage))
                    {
                        ContabDB.Dispose();

                        ErrMessage_Span.InnerHtml        = sErrorMessage;
                        ErrMessage_Span.Style["display"] = "block";

                        return;
                    }

                    nMesFiscal         = MyGetMesFiscalContable.MesFiscal;
                    nAnoFiscal         = MyGetMesFiscalContable.AnoFiscal;
                    nMesCalendario     = MyGetMesFiscalContable.MesCalendario;
                    nAnoCalendario     = MyGetMesFiscalContable.AnoCalendario;
                    sNombreMes         = MyGetMesFiscalContable.NombreMes;
                    dFechaSaldoInicial = MyGetMesFiscalContable.FechaSaldo;

                    nCiaContabAnterior = MyBalanceComprobacion_Record2.Cia;
                }

                // determinamos el saldo anterior de cada cuenta (GetSaldoContable es una clase que está en: old_app_code/Generales2.cs)
                GetSaldoContable MyGetSaldoContable = new GetSaldoContable(MyBalanceComprobacion_Record2.CuentaContableID,
                                                                           nMesFiscal,
                                                                           nAnoFiscal,
                                                                           dFechaInicialPeriodoIndicado,
                                                                           MyBalanceComprobacion_Record2.Moneda,
                                                                           MyBalanceComprobacion_Record2.Cia, bReconvertirCifrasAntes_01Oct2021, monedaNacional.Moneda);

                MyGetSaldoContable.bLeerSaldoCuenta();

                decimal nSaldoAnteriorContable = MyGetSaldoContable.SaldoAnterior;

                MyBalanceComprobacion_Record2.SaldoAnterior = nSaldoAnteriorContable;

                // este método lee los movimientos para la cuenta, la moneda y el período
                var result = determinarMovimientoCuentaContable.leerMovimientoCuentaContable(MyBalanceComprobacion_Record2.CuentaContableID, MyBalanceComprobacion_Record2.Moneda);

                MyBalanceComprobacion_Record2.Debe  = result.sumDebe;
                MyBalanceComprobacion_Record2.Haber = result.sumHaber;
                MyBalanceComprobacion_Record2.CantidadMovimientos = result.recCount;

                // --------------------------------------------------------------------------------------------------------------------
                // por último, leemos la descripción del 'nivel previo' de la cuenta
                string selectDescripcionNivelPrevio = "Select Descripcion From CuentasContables Where Cuenta = {0} And Cia = {1}";

                object[] parameters = { MyBalanceComprobacion_Record2.NivelPrevioCuentaContable, MyBalanceComprobacion_Record2.Cia };
                string   sCuentaContable_NivelPrevio_Descripcion = dbContext.ExecuteStoreQuery <string>(selectDescripcionNivelPrevio, parameters).FirstOrDefault();

                MyBalanceComprobacion_Record2.NivelPrevioCuentaContable_Nombre = sCuentaContable_NivelPrevio_Descripcion;
                MyBalanceComprobacion_Record2.SaldoActual = MyBalanceComprobacion_Record2.SaldoAnterior + MyBalanceComprobacion_Record2.Debe - MyBalanceComprobacion_Record2.Haber;

                // --------------------------------------------------------------------------------------
                // para mostrar el progreso al usuario

                nRegistroActual    += 1;
                nProgreesPercentaje = nRegistroActual * 100 / nCantidadRegistros;

                Session["Progress_Percentage"]   = nProgreesPercentaje;
                Session["Progress_SelectedRecs"] = (int)Session["Progress_SelectedRecs"] + 1;
            }

            // tenemos los niveles 'previos' de cada cuenta; vamos a crear una lista con las descripciones de cada cuenta, para luego
            // leer las mismas y completar los niveles previos en la lista. Para cada nivel, ej: 0101002, quedará así: 0101002 - <su descripción> ...

            var queryCuentasContables = dbContext.CuentasContables.Where(c => c.TotDet == "T" && c.Cia == ciaContabSeleccionada).Select(c => new { c.Cuenta, c.Descripcion });
            List <Cuenta_Nombre> listaCuentasYNombres = new List <Cuenta_Nombre>();

            foreach (var cuenta in queryCuentasContables)
            {
                listaCuentasYNombres.Add(new Cuenta_Nombre {
                    cuenta = cuenta.Cuenta, descripcion = cuenta.Descripcion
                });
            }

            // ahora recorremos la lista y buscamos la descripción de cada cuenta contable
            foreach (BalanceComprobacion_Item item in MyBalanceComprobacion_Lista)
            {
                if (item.nivel1 != null)
                {
                    if (listaCuentasYNombres.Where(c => c.cuenta == item.nivel1).Count() > 0)
                    {
                        item.nivel1 += " - " + listaCuentasYNombres.Where(c => c.cuenta == item.nivel1).First().descripcion;
                    }
                }

                if (item.nivel2 != null)
                {
                    if (listaCuentasYNombres.Where(c => c.cuenta == item.nivel2).Count() > 0)
                    {
                        item.nivel2 += " - " + listaCuentasYNombres.Where(c => c.cuenta == item.nivel2).First().descripcion;
                    }
                }

                if (item.nivel3 != null)
                {
                    if (listaCuentasYNombres.Where(c => c.cuenta == item.nivel3).Count() > 0)
                    {
                        item.nivel3 += " - " + listaCuentasYNombres.Where(c => c.cuenta == item.nivel3).First().descripcion;
                    }
                }

                if (item.nivel4 != null)
                {
                    if (listaCuentasYNombres.Where(c => c.cuenta == item.nivel4).Count() > 0)
                    {
                        item.nivel4 += " - " + listaCuentasYNombres.Where(c => c.cuenta == item.nivel4).First().descripcion;
                    }
                }

                if (item.nivel5 != null)
                {
                    if (listaCuentasYNombres.Where(c => c.cuenta == item.nivel5).Count() > 0)
                    {
                        item.nivel5 += " - " + listaCuentasYNombres.Where(c => c.cuenta == item.nivel5).First().descripcion;
                    }
                }

                if (item.nivel6 != null)
                {
                    if (listaCuentasYNombres.Where(c => c.cuenta == item.nivel6).Count() > 0)
                    {
                        item.nivel6 += " - " + listaCuentasYNombres.Where(c => c.cuenta == item.nivel6).First().descripcion;
                    }
                }
            }

            // agregamos el contenido de la lista a la tabla
            Contab_BalanceComprobacion contabBalanceComprobacionItem;

            foreach (BalanceComprobacion_Item item in MyBalanceComprobacion_Lista)
            {
                contabBalanceComprobacionItem = new Contab_BalanceComprobacion()
                {
                    CuentaContableID                       = item.CuentaContableID,
                    Moneda                                 = item.Moneda,
                    CuentaContable_NivelPrevio             = item.NivelPrevioCuentaContable,
                    CuentaContable_NivelPrevio_Descripcion = item.NivelPrevioCuentaContable_Nombre,
                    nivel1                                 = item.nivel1,
                    nivel2                                 = item.nivel2,
                    nivel3                                 = item.nivel3,
                    nivel4                                 = item.nivel4,
                    nivel5                                 = item.nivel5,
                    nivel6                                 = item.nivel6,
                    SaldoAnterior                          = item.SaldoAnterior,
                    Debe                = item.Debe,
                    Haber               = item.Haber,
                    SaldoActual         = item.SaldoActual,
                    CantidadMovimientos = item.CantidadMovimientos,
                    NombreUsuario       = nombreUsuario
                };

                dbContext.Contab_BalanceComprobacion.AddObject(contabBalanceComprobacionItem);
            }

            try
            {
                dbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                errorMessage = ex.Message;
                if (ex.InnerException != null)
                {
                    errorMessage += "<br />" + ex.InnerException.Message;
                }

                Session["Thread_ErrorMessage"] = "Ha ocurrido un error al intentar ejecutar una operación de " +
                                                 "acceso a la base de datos. <br /> El mensaje específico de error es: " +
                                                 errorMessage + "<br />";

                Session["Progress_Completed"]  = 1;
                Session["Progress_Percentage"] = 0;

                return;
            }

            // ------------------------------------------------------------------------------------------
            // por último, eliminamos las cuentas seleccionadas de acuerdo al criterio indicado en las opciones
            if (!(bool)Session["MostrarCuentasSinSaldoYSinMvtos"])
            {
                dbContext.ExecuteStoreCommand("Delete From Contab_BalanceComprobacion Where SaldoAnterior = 0 And CantidadMovimientos = 0 And NombreUsuario = {0}", nombreUsuario);
            }

            if (!(bool)Session["MostrarCuentasConSaldoYSinMvtos"])
            {
                dbContext.ExecuteStoreCommand("Delete From Contab_BalanceComprobacion Where SaldoAnterior <> 0 And CantidadMovimientos = 0 And NombreUsuario = {0}", nombreUsuario);
            }

            if (!(bool)Session["MostrarCuentasSaldosEnCero"])
            {
                dbContext.ExecuteStoreCommand("Delete From Contab_BalanceComprobacion Where SaldoAnterior = 0 And SaldoActual = 0 And NombreUsuario = {0}", nombreUsuario);
            }

            if (!(bool)Session["MostrarCuentasSaldoFinalEnCero"])
            {
                dbContext.ExecuteStoreCommand("Delete From Contab_BalanceComprobacion Where SaldoActual = 0 And NombreUsuario = {0}", nombreUsuario);
            }

            dbContext.Dispose();

            // -----------------------------------------------------
            // por último, inicializamos las variables que se usan
            // para mostrar el progreso de la tarea
            Session["Progress_Completed"]  = 1;
            Session["Progress_Percentage"] = 0;
            // -----------------------------------------------------
        }
Пример #8
0
        public bool CopiarAsientosContables(string filter, string filter_subQuery,
                                            string userName, int ciaTarget, string multiplicarPor_textBox,
                                            string dividirPor_textBox, out int cantidadAsientosCopiados, out string errorMessage)
        {
            errorMessage             = "";
            cantidadAsientosCopiados = 0;

            // sabemos que ambos controles, si tienen un valor, debe ser numérico; nota: también pueden venir vacíos ...
            double multiplicarPor = multiplicarPor_textBox.Trim() != "" ? Convert.ToDouble(multiplicarPor_textBox) : 1;
            double dividirPor     = dividirPor_textBox.Trim() != "" ? Convert.ToDouble(dividirPor_textBox) : 1;

            string filtroAsientosContables = "";

            if (filter_subQuery == null || filter_subQuery == "1 = 1")
            {
                // el usuario no usó criterio por cuenta contable o más de 2 decimales; no usamos sub-query
                filtroAsientosContables = filter;
            }
            else
            {
                // si el usuario indica cuentas contables en su filtro, debemos hacer un subquery para que el resultado final
                // solo incluya asientos que las tengan ...
                filtroAsientosContables = filter +
                                          " And (Asientos.NumeroAutomatico In (SELECT Asientos.NumeroAutomatico FROM Asientos " +
                                          "Left Outer Join dAsientos On Asientos.NumeroAutomatico = dAsientos.NumeroAutomatico " +
                                          "Left Outer Join CuentasContables On CuentasContables.ID = dAsientos.CuentaContableID " +
                                          "Where " + filter + " And " + filter_subQuery + "))";
            }

            // como el filtro viene para Sql, y no para linq to entities, intentamos leer los asientos usando Sql ...
            var query = _context.ExecuteStoreQuery <Asiento>("Select * from Asientos Where" + filtroAsientosContables + " Order By Asientos.Fecha, Asientos.Numero");

            int mesAnterior = -99;
            int anoAnterior = -99;

            short mesFiscal = 0;
            short anoFiscal = 0;

            Asiento  asiento;
            dAsiento partida;

            foreach (Asiento a in query)
            {
                if (mesAnterior != a.Fecha.Month || anoAnterior != a.Fecha.Year)
                {
                    // para cada mes diferente, validamos que el mes no esté cerrado en la compañía 'target' ...
                    if (!ValidarMesCerradoEnContab(a.Fecha, ciaTarget, out mesFiscal, out anoFiscal, out errorMessage))
                    {
                        return(false);
                    }

                    mesAnterior = a.Fecha.Month;
                    anoAnterior = a.Fecha.Year;
                }

                // determinamos un número para el asiento contable en ciaTarget ...
                short numeroAsientoContab = 0;

                if (!ObtenerNumeroAsientoContab(a.Fecha, ciaTarget, a.Tipo, out numeroAsientoContab, out errorMessage))
                {
                    return(false);
                }

                asiento = new Asiento();

                asiento.Mes                        = a.Mes;
                asiento.Ano                        = a.Ano;
                asiento.Numero                     = numeroAsientoContab;
                asiento.Fecha                      = a.Fecha;
                asiento.Tipo                       = a.Tipo;
                asiento.Descripcion                = a.Descripcion;
                asiento.Moneda                     = a.Moneda;
                asiento.MonedaOriginal             = a.MonedaOriginal;
                asiento.ConvertirFlag              = a.ConvertirFlag;
                asiento.FactorDeCambio             = a.FactorDeCambio;
                asiento.ProvieneDe                 = a.ProvieneDe;
                asiento.Ingreso                    = DateTime.Now;
                asiento.UltAct                     = DateTime.Now;
                asiento.CopiableFlag               = a.CopiableFlag;
                asiento.AsientoTipoCierreAnualFlag = false;         // nótese como nunca asumimos que un asiento de cierre anual lo es también en Cia Target ...
                asiento.MesFiscal                  = mesFiscal;
                asiento.AnoFiscal                  = anoFiscal;
                asiento.Usuario                    = userName;
                asiento.Cia                        = ciaTarget;

                // leemos las partidas del asiento y las copiamos al nuevo ...
                var partidas = _context.dAsientos.Where(p => p.NumeroAutomatico == a.NumeroAutomatico).OrderBy(p => p.Partida);

                foreach (dAsiento p in partidas)
                {
                    partida = new dAsiento();

                    // para cada cuenta contable, debemos buscar una idéntica en la compañía target ...
                    int?cuentaContableCiaTarget = _context.CuentasContables.Where(c => c.Cuenta == p.CuentasContable.Cuenta).
                                                  Where(c => c.Cia == ciaTarget).
                                                  Select(c => c.ID).
                                                  FirstOrDefault();

                    if (cuentaContableCiaTarget == null || cuentaContableCiaTarget == 0)
                    {
                        errorMessage = "<b>Error:</b> no hemos podido leer la cuenta contable '" + p.CuentasContable.Cuenta + "' en la compañía indicada.";
                        return(false);
                    }

                    partida.Partida          = p.Partida;
                    partida.CuentaContableID = cuentaContableCiaTarget.Value;
                    partida.Descripcion      = p.Descripcion;
                    partida.Referencia       = p.Referencia;

                    // multiplicamos y dividimos por lo montos que indique el usuario; nota: si no indica estos montos, usamos 1 ...
                    partida.Debe  = Convert.ToDecimal((Convert.ToDouble(p.Debe) * multiplicarPor) / dividirPor);
                    partida.Haber = Convert.ToDecimal((Convert.ToDouble(p.Haber) * multiplicarPor) / dividirPor);

                    asiento.dAsientos.Add(partida);
                }

                _context.Asientos.AddObject(asiento);
                cantidadAsientosCopiados++;
            }

            try
            {
                _context.SaveChanges();
            }
            catch (Exception ex)
            {
                errorMessage = "<b>Error:</b> hemos obtenido un error al intentar efectuar una operación en la " +
                               "base de datos.<br /><br />" +
                               "El mensaje específico de error es: <br /><br />" + ex.Message;

                if (ex.InnerException != null)
                {
                    errorMessage += "<br />" + ex.InnerException.Message;
                }

                return(false);
            }
            finally
            {
                _context = null;
            }

            return(true);
        }