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 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 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 (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; // ----------------------------------------------------- }