From 0e01ecbc278921593ca209d08fa40b12af7651e2 Mon Sep 17 00:00:00 2001 From: JPerez Date: Fri, 6 Jun 2025 13:00:46 -0700 Subject: [PATCH 01/11] --Excluir facturas canceladas al relacionar cfdi --- Ventas/Ventas.aspx.vb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Ventas/Ventas.aspx.vb b/Ventas/Ventas.aspx.vb index 7f559bd4a..2426570ff 100644 --- a/Ventas/Ventas.aspx.vb +++ b/Ventas/Ventas.aspx.vb @@ -13890,7 +13890,8 @@ Partial Class Ventas If Obj.TipoDocto.Contiene("Egs", "Dev") OrElse (NuevaFactura = 1) Then If DtVentasNC IsNot Nothing AndAlso DtVentasNC.Rows.Count > 0 Then Timbre.CFDIRelacionados.UUID.Clear() - For Each Dr As DataRow In DtVentasNC.Rows + 'QUITAR LAS QUE ESTEN CANCELADAS + For Each Dr As DataRow In DtVentasNC.FiltraParametros("CveEstatusFactura <> 5").Rows Timbre.CFDIRelacionados.UUID.Add(Dr("FolioFiscal").ToString()) Next Else From 6a8ba84dc820f39ee64ad953cac65c5d438a622e Mon Sep 17 00:00:00 2001 From: JPerez Date: Fri, 6 Jun 2025 13:03:15 -0700 Subject: [PATCH 02/11] --Sobrante y faltante cuando se aplican anticipos --- Ventas/PVCobranza.aspx.vb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Ventas/PVCobranza.aspx.vb b/Ventas/PVCobranza.aspx.vb index 9b02686b4..835e0e09b 100644 --- a/Ventas/PVCobranza.aspx.vb +++ b/Ventas/PVCobranza.aspx.vb @@ -906,6 +906,23 @@ Partial Class Ventas_PVCobranza SaldoPendientePagos -= PagoEfectivo End If + If SobranteFaltante <> 0 Then + Dim Pago As New VentaPago + Pago.ImportePagoVenta = Math.Abs(SobranteFaltante) + Pago.ImportePago = Math.Abs(SobranteFaltante) + Pago.CveIE = -1 + Pago.CveMonedaPago = VentaActual.CveMoneda + Pago.Fecha = NowADS() + Pago.Referencia = VentaActual.SerieFolio + Pago.TipoPago = "XXX" + Pago.OtroGastoIngreso = SobranteFaltante + + Dim ErrorConta As Boolean = AplicaPrePolizaPagoVenta(VentaActual, Pago, CvePrePoliza, ObjConta) + If ErrorConta Then + MsgError = "Error en aplicación de sobrante/faltante" + End If + End If + If SaldoPendienteVenta > 0 AndAlso Not ChkSobFaltante.Checked Then MsgError = "Tiene saldo pendiente por aplicar" End If From 89a19ed959c7951d3c831b2b4292d85ad161674e Mon Sep 17 00:00:00 2001 From: JPerez Date: Fri, 6 Jun 2025 17:11:53 -0700 Subject: [PATCH 03/11] --FIX error de ultimo costo --- Ventas/Ventas.aspx.vb | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Ventas/Ventas.aspx.vb b/Ventas/Ventas.aspx.vb index a1ea5290a..2c255cd97 100644 --- a/Ventas/Ventas.aspx.vb +++ b/Ventas/Ventas.aspx.vb @@ -2866,6 +2866,8 @@ Partial Class Ventas TmpDT.Columns.Add("PSAlterno", GetType(String)) TmpDT.Columns.Add("Costo", GetType(Decimal)) TmpDT.Columns("Costo").DefaultValue = 0D + TmpDT.Columns.Add("UltimoCosto", GetType(Decimal)) + TmpDT.Columns("UltimoCosto").DefaultValue = 0D GvPS.DataSource = ObjVentas.DtResultados GvPS.DataBind() @@ -2887,6 +2889,8 @@ Partial Class Ventas TmpDT = ObjCGame.DtResultados TmpDT.Columns.Add("Costo", GetType(Decimal)) TmpDT.Columns("Costo").DefaultValue = 0D + TmpDT.Columns.Add("UltimoCosto", GetType(Decimal)) + TmpDT.Columns("UltimoCosto").DefaultValue = 0D If Not TmpDT.Columns.Contains("NumeroParte") Then TmpDT.Columns.Add("NumeroParte", GetType(String)) GvPS.DataBind() @@ -2935,6 +2939,9 @@ Partial Class Ventas TmpDT.Columns.Add("NumeroParte", GetType(String)) TmpDT.Columns.Add("Costo", GetType(Decimal)) TmpDT.Columns("Costo").DefaultValue = 0D + TmpDT.Columns.Add("UltimoCosto", GetType(Decimal)) + TmpDT.Columns("UltimoCosto").DefaultValue = 0D + GvPS.DataSource = ObjVentas.DtResultados GvPS.DataBind() @@ -9283,6 +9290,9 @@ Partial Class Ventas If DrPS IsNot Nothing Then gvr.FCTextBox("TxtPrecio").Enabled = CBool(DrPS("PrecioLibre")) End If + + 'PONER LA CLASIFICACION EN TODAS, PARA NO FILTRAR POR CLASIFICACION + gvr.FCDropDownList("DdlClasificacion").SelectedValueExist("-1") End If If UsuarioActual.TienePermisoProceso(253) Then gvr.FCTextBox("TxtPrecio").Enabled = True @@ -10381,7 +10391,6 @@ Partial Class Ventas PU = dr("PU").ToString().ToDecimal * If(DdlMoneda.SelectedValue.ToEntero() = 1, 1, TxtTipoCambio.Text.ToDecimal) If UsuarioActual.Empresa.Funcionalidad(602) = "UC" Then 'validación sobre el último costo - If ObjInventarios.GetUltimoCosto(UsuarioActual.CveEmpresa, dr("CvePS").ToString().ToEntero()) Then Dim drps As DataRow = ObjInventarios.DtResultados.FiltroPrimero("") If drps IsNot Nothing Then @@ -10391,6 +10400,7 @@ Partial Class Ventas Else Costo = ObjInventarios.GetCostoPS(dr("CvePS").ToString().ToEntero(), dr("Cantidad").ToString().ToDecimal, -1, "-1", TxtFecha.Text.ToDate, DdlSubProyectoDatos.SelectedValue.ToEntero(), CveTipoAlmacen:=1) End If + Dim PrecioMinimo As Decimal = 0 'RMF. condicion temporal, para reubicación, precio mínimo If UsuarioActual.CveEmpresa = 119 Then @@ -13781,13 +13791,7 @@ Partial Class Ventas Timbre.Comprobante.TipoComprobante = If(Obj.TipoDocto.Contiene("Ing", "Ant"), "I", If(Obj.TipoDocto.Contiene("Egs", "Dev"), "E", "")) Timbre.Comprobante.Folio = Obj.Folio.ToString() Timbre.Comprobante.Serie = Obj.Serie - - If Me.CveVenta = 4381091 Then - Timbre.Comprobante.Fecha = Obj.Fecha - Else - Timbre.Comprobante.Fecha = Obj.FechaCP - End If - + Timbre.Comprobante.Fecha = Obj.FechaCP Timbre.Comprobante.CondicionesdePago = If(UsuarioActual.CveEmpresa.Contiene(15, 76, 198), "No Aplica", Obj.FormaPago) Timbre.Comprobante.MetodoPago = GlobalDTVtaMetodoPago.FiltroPrimeroValor("ClaveMetodoPagoSAT", $"CveMetodoPago = {Obj.CveMetodoPago}") ' Obj.ClaveMetodoPagoSAT @@ -21691,6 +21695,9 @@ Partial Class Ventas TmpDT.Columns.Add("Costo", GetType(Decimal)) TmpDT.Columns("Costo").DefaultValue = 0D + + TmpDT.Columns.Add("UltimoCosto", GetType(Decimal)) + TmpDT.Columns("UltimoCosto").DefaultValue = 0D End Sub Private Sub CreaDTmpC() DTmpC = New DataTable From 96a15382d0066e9c2872648d3d9b12c2e2d15eab Mon Sep 17 00:00:00 2001 From: Luis Carlos Quijada Date: Sat, 7 Jun 2025 13:21:09 -0600 Subject: [PATCH 04/11] Cambios en Dashboard Opcion 4 --- App_Code/ClsGenerales.vb | 46 +- App_Code/ClsVentas.vb | 3 +- General/Dashboard.aspx | 1386 +++++++++++++++---------------------- General/Dashboard.aspx.vb | 646 ++++++++++++++++- Inicio.aspx.vb | 2 +- OP/OP.aspx | 64 +- OP/OP.aspx.vb | 54 +- 7 files changed, 1290 insertions(+), 911 deletions(-) diff --git a/App_Code/ClsGenerales.vb b/App_Code/ClsGenerales.vb index 5ce060b9a..1e444e23b 100644 --- a/App_Code/ClsGenerales.vb +++ b/App_Code/ClsGenerales.vb @@ -399,15 +399,43 @@ Public Class ClsGenerales Try SqlAdapter.Fill(DSet) - DSet.Tables(0).TableName = "Indicadores" - DSet.Tables(1).TableName = "DetalleDia" - DSet.Tables(2).TableName = "DetalleAnualesMes" - DSet.Tables(3).TableName = "VentasPorVendedor" - DSet.Tables(4).TableName = "VentasPorClasificacion" - DSet.Tables(5).TableName = "VentasPorMarca" - DSet.Tables(6).TableName = "VentasPorPS" - DSet.Tables(7).TableName = "VentasPorCliente" - DSet.Tables(8).TableName = "VentasPorProveedor" + If DSet.Tables.Count > 0 Then + Select Case Opcion + Case 1 ' Cuentas por Cobrar + DSet.Tables(0).TableName = "Indicadores" + If DSet.Tables.Count > 1 Then DSet.Tables(1).TableName = "DetalleDia" + If DSet.Tables.Count > 2 Then DSet.Tables(2).TableName = "DetalleAnualesMes" + If DSet.Tables.Count > 3 Then DSet.Tables(3).TableName = "VentasPorVendedor" + If DSet.Tables.Count > 4 Then DSet.Tables(4).TableName = "VentasPorClasificacion" + If DSet.Tables.Count > 5 Then DSet.Tables(5).TableName = "VentasPorMarca" + If DSet.Tables.Count > 6 Then DSet.Tables(6).TableName = "VentasPorPS" + If DSet.Tables.Count > 7 Then DSet.Tables(7).TableName = "VentasPorCliente" + If DSet.Tables.Count > 8 Then DSet.Tables(8).TableName = "VentasPorProveedor" + + Case 2 ' Recuperación + DSet.Tables(0).TableName = "CarteraPorSubproyecto" + If DSet.Tables.Count > 1 Then DSet.Tables(1).TableName = "CarteraPorVendedor" + If DSet.Tables.Count > 2 Then DSet.Tables(2).TableName = "RecuperacionPorSubproyecto" + If DSet.Tables.Count > 3 Then DSet.Tables(3).TableName = "RecuperacionPorVendedor" + If DSet.Tables.Count > 4 Then DSet.Tables(4).TableName = "RecuperacionPorCliente" + If DSet.Tables.Count > 5 Then DSet.Tables(5).TableName = "CxCMensual" + + + Case 3 'Compras + If DSet.Tables.Count > 1 Then DSet.Tables(1).TableName = "ComprasPorClasificación" + If DSet.Tables.Count > 2 Then DSet.Tables(2).TableName = "ComprasPorMarca" + If DSet.Tables.Count > 3 Then DSet.Tables(3).TableName = "ComprasPorPS" + If DSet.Tables.Count > 4 Then DSet.Tables(4).TableName = "ComprasPorProveedor" + + Case 4 'Cuentas Por Pagar + DSet.Tables(0).TableName = "CxPPorSubproyecto" + If DSet.Tables.Count > 1 Then DSet.Tables(1).TableName = "CxPPorProveedor" + If DSet.Tables.Count > 2 Then DSet.Tables(2).TableName = "PagosPorSubproyecto" + If DSet.Tables.Count > 3 Then DSet.Tables(3).TableName = "PagosPorProveedor" + If DSet.Tables.Count > 4 Then DSet.Tables(4).TableName = "CxPMensual" + End Select + End If + Catch ex As Exception ' Manejo de errores diff --git a/App_Code/ClsVentas.vb b/App_Code/ClsVentas.vb index 8b83de472..f6abba49c 100644 --- a/App_Code/ClsVentas.vb +++ b/App_Code/ClsVentas.vb @@ -7728,7 +7728,7 @@ Public Class ClsVentas End Function - Public Function GetSMSIndicadores(Opcion As Integer, FechaInicio As Date, FechaFin As Date, CveUsuario As Integer, CveVendedor As Integer, CveGerenteVendedor As Integer, CveUsuarioTecnico As Integer, CveEmpresa As Integer) As Boolean + Public Function GetSMSIndicadores(Opcion As Integer, FechaInicio As Date, FechaFin As Date, CveUsuario As Integer, CveVendedor As Integer, CveUsuarioTecnico As Integer, CveEmpresa As Integer) As Boolean Dim Retorno As Boolean = False DataAdapter("PA_SMS_IndicadoresGet") With SqlAdapter.SelectCommand.Parameters @@ -7737,7 +7737,6 @@ Public Class ClsVentas .Add("@FechaFin", SqlDbType.Date).Value = FechaFin .Add("@CveUsuario", SqlDbType.Int).Value = CveUsuario .Add("@CveVendedor", SqlDbType.Int).Value = CveVendedor - .Add("@CveGerenteVendedor", SqlDbType.Int).Value = CveGerenteVendedor .Add("@CveUsuarioTecnico", SqlDbType.Int).Value = CveUsuarioTecnico .Add("@CveEmpresa", SqlDbType.Int).Value = CveEmpresa End With diff --git a/General/Dashboard.aspx b/General/Dashboard.aspx index 213c8a410..f3052b6ab 100644 --- a/General/Dashboard.aspx +++ b/General/Dashboard.aspx @@ -41,523 +41,16 @@ padding-right: 15px; } - .blue { - background: #3598dc; - } - - .green { - background: #32c5d2; - } - - .purple { - background: #8e44ad; - } - - .red { - background: #e7505a; - } - - .indicador-valor { - font-size: 24px; - font-weight: bold; - } - - .indicador-detalle { - margin-top: 10px; - } - - - .unoaunoold { - color: #999b9b; - font-size: 11px; - } - - .Dia { - background-image: url(/Imagenes/FondoCal.jpg); - background-repeat: repeat-x; - height: 17px; - font-size: 10px; - text-align: right; - } - - .Hora { - background-color: #E3EFFF; - height: 30px; - font-size: 10px; - border-right: solid 1px #5D8CC9; - border-bottom: solid 1px #5D8CC9; - } - - .Mes { - background-image: url(/Imagenes/Caption.jpg); - height: 27px; - } - .Link { color: #0000b9; } - .calendariopanel { - z-index: 999; - width: 100%; - height: 100%; - top: 0px; - left: 0px; - border: 0px; - background-color: transparent; - position: absolute; - } - - .calendarioback { - background-color: #000; - z-index: -90; - top: 0px; - opacity: 0.3; - position: fixed; - width: 100%; - height: 100%; - } - - .calendariobody { - width: 520px; - display: table; - background-color: #fff; - margin-top: 7%; - margin-left: 28%; - } - - .calendariobody label { - font-size: 12px; - } - - .tareasinicio tr td:nth-child(1) { - } - .portlet.light > .portlet-title > .caption > .caption-subject { font-size: 16px; } - .fix > div { - height: inherit !important; - width: inherit !important; - } - - - .fix > div > .ajax__html_editor_extender_texteditor { - height: 150px !important; - } - - /*#overlay a:hover { - position: fixed; - display: none; - width: 100%; - height: 100%; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0,0,0,0.5); - z-index: 2; - cursor: pointer; - }*/ - - - #moopio a { - display: block; - } - - #moopio a:hover { - background-color: rgba(0,0,0,0.5); - transform: scale(1.2); - cursor: default; - } - - - .MultiLineTextBox { - resize: none; - } - - - .select2-container--open { - z-index: 1000 !important; - } - - - - - #divsmsdash { - /* Estilo general compacto */ - --hcg-font-size: 8px !important; - --hcg-padding: 4px; - --hcg-border-radius: 6px; - } - .dashboard-container { - font-size: 16px; /* Tamaño base */ - } - - .highcharts-data-table table { - /* Estilo general compacto */ - --hcg-font-size: 8px !important; - --hcg-padding: 4px; - --hcg-border-radius: 6px; - } - - #divsmsdash .hcg-theme-default, .highcharts-datagrid-theme-default { - --hcg-font-size: 10px; - --hcg-padding: 5px; - } - - .highcharts-figure, - .highcharts-data-table table { - min-width: 310px; - max-width: 800px; - margin: 1em auto; - } - - #container { - height: 400px; - } - - .highcharts-data-table table { - font-family: Verdana, sans-serif; - border-collapse: collapse; - border: 1px solid #ebebeb; - margin: 10px auto; - text-align: center; - width: 100%; - max-width: 500px; - } - - .highcharts-data-table caption { - padding: 1em 0; - font-size: 1.2em; - color: #555; - } - - .highcharts-data-table th { - font-weight: 600; - padding: 0.5em; - } - - .highcharts-data-table td, - .highcharts-data-table th, - .highcharts-data-table caption { - padding: 0.5em; - } - - .highcharts-data-table thead tr, - .highcharts-data-table tr:nth-child(even) { - background: #f8f8f8; - } - - .highcharts-data-table tr:hover { - background: #f1f7ff; - } - - .highcharts-description { - margin: 0.3rem 10px; - } - - h1#title { - padding-top: 10px; - margin: 0; - background-color: #3d3d3d; - text-align: center; - color: #fff; - } - - #kpi-vitamin-a .highcharts-dashboards-component-title::before, - #kpi-iron .highcharts-dashboards-component-title::before { - width: 14px; - height: 14px; - border-radius: 28px; - display: inline-block; - padding: 0; - margin-right: 4px; - background-color: var(--highcharts-color-0); - content: " "; - } - - #kpi-iron .highcharts-dashboards-component-title::before { - background-color: var(--highcharts-color-2); - } - - #kpi-vitamin-a .highcharts-dashboards-component-kpi-subtitle, - #kpi-iron .highcharts-dashboards-component-kpi-subtitle { - margin-top: 10px; - font-size: 1.2em; - color: var(--highcharts-neutral-color-60); - } - - #kpi-vitamin-a .highcharts-dashboards-component-kpi-value, - #kpi-iron .highcharts-dashboards-component-kpi-value { - font-size: 4em; - line-height: 2.4rem; - margin-top: 10px; - color: var(--highcharts-color-0); - } - - #kpi-iron .highcharts-dashboards-component-kpi-value { - color: var(--highcharts-color-2); - } - - #dashboard-col-1 .highcharts-color-0 { - fill: var(--highcharts-color-2); - stroke: var(--highcharts-color-2); - } - - #kpi-vitamin-a .highcharts-dashboards-component-kpi-value::after, - #kpi-iron .highcharts-dashboards-component-kpi-value::after { - content: ""; - display: block; - font-size: 1rem; - } - - .highcharts-plot-line { - stroke-dasharray: 2px; - stroke: var(--highcharts-color-3); - } - - .highcharts-plot-line-label { - fill: var(--highcharts-color-3); - } - - .highcharts-description { - padding: 0 20px; - } - - #kpi-vitamin-a, - #kpi-iron { - flex: 1 1 100%; - height: 205px; - } - - /* LARGE */ - @media (max-width: 1200px) { - #dashboard-col-0, - #dashboard-col-1 { - flex: 1 1 35%; - } - - #kpi-wrapper { - flex: 1 1 30%; - } - - #kpi-vitamin-a, - #kpi-iron { - flex: 1 1 100%; - } - } - - /* MEDIUM */ - @media (max-width: 992px) { - #dashboard-col-0, - #dashboard-col-1 { - flex: 1 1 50%; - } - - #kpi-wrapper { - flex: 1 1 100%; - } - - #kpi-vitamin-a, - #kpi-iron { - flex: 1 1 50%; - } - } - - /* SMALL */ - @media (max-width: 576px) { - #dashboard-col-0, - #dashboard-col-1 { - flex: 1 1 100%; - } - - #kpi-wrapper { - flex: 1 1 100%; - } - - #kpi-vitamin-a, - #kpi-iron { - flex: 1 1 50%; - } - } - - .highcharts-figure, - .highcharts-data-table table { - min-width: 310px; - max-width: 800px; - margin: 1em auto; - } - - #container { - height: 400px; - } - - .highcharts-data-table table { - font-family: Verdana, sans-serif; - border-collapse: collapse; - border: 1px solid #ebebeb; - margin: 10px auto; - text-align: center; - width: 100%; - max-width: 500px; - } - - .highcharts-data-table caption { - padding: 1em 0; - font-size: 1.2em; - color: #555; - } - - .highcharts-data-table th { - font-weight: 600; - padding: 0.5em; - } - - .highcharts-data-table td, - .highcharts-data-table th, - .highcharts-data-table caption { - padding: 0.5em; - } - - .highcharts-data-table thead tr, - .highcharts-data-table tr:nth-child(even) { - background: #f8f8f8; - } - - .highcharts-data-table tr:hover { - background: #f1f7ff; - } - - .highcharts-description { - margin: 0.3rem 10px; - } - - h1#title { - padding-top: 10px; - margin: 0; - background-color: #3d3d3d; - text-align: center; - color: #fff; - } - - #kpi-vitamin-a .highcharts-dashboards-component-title::before, - #kpi-iron .highcharts-dashboards-component-title::before { - width: 14px; - height: 14px; - border-radius: 28px; - display: inline-block; - padding: 0; - margin-right: 4px; - background-color: var(--highcharts-color-0); - content: " "; - } - - #kpi-iron .highcharts-dashboards-component-title::before { - background-color: var(--highcharts-color-2); - } - - #kpi-vitamin-a .highcharts-dashboards-component-kpi-subtitle, - #kpi-iron .highcharts-dashboards-component-kpi-subtitle { - margin-top: 10px; - font-size: 1.2em; - color: var(--highcharts-neutral-color-60); - } - - #kpi-vitamin-a .highcharts-dashboards-component-kpi-value, - #kpi-iron .highcharts-dashboards-component-kpi-value { - font-size: 4em; - line-height: 2.4rem; - margin-top: 10px; - color: var(--highcharts-color-0); - } - - #kpi-iron .highcharts-dashboards-component-kpi-value { - color: var(--highcharts-color-2); - } - - #dashboard-col-1 .highcharts-color-0 { - fill: var(--highcharts-color-2); - stroke: var(--highcharts-color-2); - } - - #kpi-vitamin-a .highcharts-dashboards-component-kpi-value::after, - #kpi-iron .highcharts-dashboards-component-kpi-value::after { - content: ""; - display: block; - font-size: 1rem; - } - - .highcharts-plot-line { - stroke-dasharray: 2px; - stroke: var(--highcharts-color-3); - } - - .highcharts-plot-line-label { - fill: var(--highcharts-color-3); - } - - .highcharts-description { - padding: 0 20px; - } - - #kpi-vitamin-a, - #kpi-iron { - flex: 1 1 100%; - height: 205px; - } - - /* LARGE */ - @media (max-width: 1200px) { - #dashboard-col-0, - #dashboard-col-1 { - flex: 1 1 35%; - } - - #kpi-wrapper { - flex: 1 1 30%; - } - - #kpi-vitamin-a, - #kpi-iron { - flex: 1 1 100%; - } - } - - /* MEDIUM */ - @media (max-width: 992px) { - #dashboard-col-0, - #dashboard-col-1 { - flex: 1 1 50%; - } - - #kpi-wrapper { - flex: 1 1 100%; - } - - #kpi-vitamin-a, - #kpi-iron { - flex: 1 1 50%; - } - } - - /* SMALL */ - @media (max-width: 576px) { - #dashboard-col-0, - #dashboard-col-1 { - flex: 1 1 100%; - } - - #kpi-wrapper { - flex: 1 1 100%; - } - - #kpi-vitamin-a, - #kpi-iron { - flex: 1 1 50%; - } + font-size: 16px; } .resumen-grid { @@ -580,15 +73,14 @@ .sub-columns { - /* Cambiamos de grid a flex para que cada div se distribuya correctamente */ display: flex !important; justify-content: space-between; - gap: 1rem; /* espacio entre Venta y Utilidad */ + gap: 1rem; } .sub-columns > div { - flex: 1 1 0; /* igual ancho para cada uno, y que puedan encoger */ - min-width: 0; /* PERMITIR que el contenido se encoja y rompa línea si es muy largo */ + flex: 1 1 0; + min-width: 0; } .sub-header { @@ -605,13 +97,7 @@ border-left: none; } - .row.gx-4 { - column-gap: 1.5rem; - } - .row.gy-4 { - row-gap: 1.5rem; - } .dashboard-stat { padding: 1.5rem; @@ -619,7 +105,7 @@ color: white; } - /* Estilo base para todos los GridViews */ + .custom-grid { -webkit-text-size-adjust: 100%; line-height: 1.42857; @@ -637,19 +123,19 @@ border-collapse: collapse; } - /* Para que los encabezados capitalicen sólo la primera letra */ + .custom-grid th { text-transform: capitalize; } .custom-grid th, .custom-grid td { - border: none !important; /* Quita todas las líneas */ + border: none !important; } - /* Opcional: quita cualquier padding extra en encabezados */ + .custom-grid thead th { padding: 2px !important; } @@ -664,13 +150,13 @@ - /* Línea gruesa bajo los títulos */ + .custom-grid thead th, .resumen-grid thead th { border-bottom: 2px solid #dee2e6 !important; } - /* Línea fina entre filas de datos */ + .custom-grid tbody tr + tr td, .resumen-grid tbody tr + tr td { border-top: 1px solid #dee2e6 !important; @@ -682,49 +168,39 @@ text-transform: capitalize !important; } - /* Evita overflow horizontal */ + .custom-grid { table-layout: fixed; } - /* Envuelve texto largo */ + .custom-grid td, .custom-grid th { white-space: normal !important; word-wrap: break-word !important; } - /* Habilita scrolling horizontal si aún se desborda */ - .table-responsive { - overflow-x: auto; - } - .custom-grid, .resumen-grid { font-size: 8px !important; } - /* Reduce el padding de celdas encabezado/datos a 4px */ + .custom-grid th, .custom-grid td { padding: 2px !important; } - /* Define alto fijo y padding reducido en el contenedor scrollable */ - .portlet-body.table-responsive { - padding: 2px !important; - max-height: 170px !important; - overflow-y: auto; /* si necesitas scroll vertical */ - } + .portlet { height: 200px !important; } .row.gx-4.gy-4 { - align-items: flex-start; /* Alinea siempre los portlets por arriba */ + align-items: flex-start; } - /* 1) Padding global reducido a 4px */ + .row, .portlet, .portlet-title, @@ -732,19 +208,14 @@ .dashboard-stat, .custom-grid, .resumen-grid - .highcharts-container, /* Highcharts interna */ - #divVentasMensuales /* tu contenedor de gráfica */ { + .highcharts-container, + #divVentasMensuales { padding: 2px !important; } - /* 2) Altura máxima de 250px para todos los contenedores scrollables */ - .portlet-body.table-responsive { - max-height: 170px !important; - overflow-y: auto; /* scroll interno si supera 250px */ - overflow-x: hidden; - } - /* ——— Resumen‑grid idéntico a custom‑grid ——— */ + + .resumen-grid, .custom-grid { border-collapse: collapse; @@ -755,27 +226,17 @@ .resumen-grid th, .resumen-grid td { - /* mismo borde inferior */ border: none !important; padding: 2px !important; - /* mismo wrapping */ white-space: normal !important; word-wrap: break-word !important; } - /* ——— Wrapper scrollable idéntico ——— */ - .portlet-body.table-responsive { - /* padding interior reducido */ - padding: 2px !important; - /* misma altura máxima */ - max-height: 170px !important; - overflow-y: auto; - overflow-x: hidden; - } - /* ajustar los sub‑contenedores de “Utilidad” */ + + #gvResumenSucursales .sub-columns, #gvResumenSucursales .sub-columns > div { padding: 2px !important; @@ -787,40 +248,34 @@ .custom-grid th, .resumen-grid td, .resumen-grid th { - padding: 2px !important; /* Padding uniforme de 2px */ + padding: 2px !important; vertical-align: middle !important; } - .portlet-body.table-responsive { - height: 170px !important; /* Altura exacta */ - overflow-y: auto !important; /* Scroll vertical si hay overflow */ - padding: 2px !important; /* Padding interno reducido */ + .portlet-body { + padding: 2px !important; + max-height: 170px !important; } + #gvResumenSucursales .sub-data { - padding: 2px !important; /* Padding igual al resto */ + padding: 2px !important; border-left: 1px solid #dee2e6 !important; } - /* Eliminar padding extra en sub-columnas */ + #gvResumenSucursales .sub-columns > div { padding: 0 !important; margin: 0 !important; } - /*---------------------------------------- - ANCHO DE COLUMNAS DE IMPORTES (AÑO, MES, ETC) ------------------------------------------*/ - - /* Ancho libre para primeras columnas (Sucursal, Vendedor, etc.) */ .custom-grid td:first-child, .custom-grid th:first-child { width: auto !important; min-width: auto !important; max-width: none !important; - } .custom-grid td:nth-child(2), @@ -834,7 +289,7 @@ padding-right: 8px !important; } - /* Alinear encabezados de columnas numéricas */ + .custom-grid th:nth-child(2), .custom-grid th:nth-child(3), .custom-grid th:nth-child(4), @@ -842,7 +297,7 @@ text-align: center !important; } - /* Asegurar ancho libre para primera columna */ + .custom-grid td:first-child, .custom-grid th:first-child { width: auto !important; @@ -851,26 +306,26 @@ } .portlet-title { - margin-bottom: 0px !important; /* Reducir espacio inferior */ - padding: 2px 0 !important; /* Padding vertical mínimo */ + margin-bottom: 0px !important; + padding: 2px 0 !important; } .portlet-title .caption-subject { - font-size: 14px !important; /* Tamaño de fuente compacto */ + font-size: 14px !important; } - /* 1) Restauramos la posición natural de la tabla */ + .portlet.light > .portlet-body.table-responsive { padding-top: 0 !important; margin-top: -16px !important; } - /* 2) Dibujamos la línea separadora justo después del título */ + .portlet.light > .portlet-title { - position: relative; /* para el pseudo-elemento */ - margin-bottom: 0 !important; /* sin espacios extra */ + position: relative; + margin-bottom: 0 !important; padding-bottom: 0 !important; } @@ -880,8 +335,8 @@ bottom: 14px; left: 0; width: 100%; - height: 2px; /* grosor de la línea */ - background-color: #dee2e6; /* mismo color que tus tablas */ + height: 2px; + background-color: #dee2e6; pointer-events: none; z-index: 1; } @@ -891,6 +346,38 @@ margin-bottom: 0 !important; padding-bottom: 0 !important; } + + + .kpi-titulo { + font-size: 14px; + font-weight: bold; + text-align: left; + margin-bottom: 10px; + padding-left: 10px; + position: relative; + padding-right: 180px; + line-height: 1.3; + } + + .kpi-valor { + font-size: 50px; + text-align: center; + font-weight: bold; + line-height: 1.2; + margin: 15px 0; + } + + .divContainerads { + + max-height: 170px; + +} + /* +.gvMaxHeight{ + max-height: 160px; + overflow: auto; +} +*/ @@ -914,14 +401,13 @@ Ingresos Recuperación Compras - Gasto - Cuentas por Pagar - Inventario - Utilidad - Impuestos - CRM - RH - AF + Cuentas por Pagar + Inventario + Utilidad + Impuestos + CRM + RH + AF @@ -930,298 +416,419 @@ -
-
-
+
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + Utilidad +
+
+
+ + + + + + + + + + + + +
+
+
+ +
+
+
+ +
+ +
+ +
+
+
+
+ Ventas por sucursal +
+
+
+ + + + + + + + + + +
+
+
+ +
+
+
+
+ Ventas por vendedor +
+
+
+ + + + + + + + + +
+
+
+ +
+ +
+ +
+
+
+
+ Ventas por clasificación +
+
+
+ + + + + + + + + +
+
+
+ +
+
+
+
+ Ventas por marca +
+
+
+ + + + + + + + + +
+
+
+
+ +
+
+
+
+
+ Ventas por PS +
+
+
+ + + + + + + + + +
+
+
+ +
+
+
+
+ Ventas por Cliente +
+
+
+ + + + + + + + + +
+
+
+
+ +
+ +
+
+
+
+ Ventas por Proveedor +
+
+
+ + + + + + + + + +
+
+
+
+
+ + + + + + +
+ +
+
+
+ +
+
+
+ +
+ +
+ +
+
+
+ +
+ +
+ +
- - Utilidad + Cartera por Sucursal
-
- - + + Width="100%"> - - - - - - - - -
-
- -
- -
- -
- -
- -
- -
-
-
-
- Ventas por sucursal -
-
-
- - - - <%# Eval("Sucursal") %> - - - <%# Eval("Año", "{0:N2}") %> - - - <%# Eval("Mes", "{0:N2}") %> - - - <%# Eval("Semana", "{0:N2}") %> - - - <%# Eval("Día", "{0:N2}") %> - + + +
- -
+
- Ventas por vendedor + Cartera por Vendedor
-
- + - - <%# Eval("Vendedor") %> - - - - <%# Eval("Año", "{0:N2}") %> - - - <%# Eval("Mes", "{0:N2}") %> - - - <%# Eval("Semana", "{0:N2}") %> - - - <%# Eval("Día", "{0:N2}") %> - + + + +
+
-
+
+ +
- Ventas por clasificación + Recuperación por Sucursal
-
- + - - <%# Eval("Clasificacion") %> - - - - <%# Eval("Año", "{0:N2}") %> - - - <%# Eval("Mes", "{0:N2}") %> - - - <%# Eval("Semana", "{0:N2}") %> - - - <%# Eval("Día", "{0:N2}") %> - + + +
- -
+
- Ventas por marca + Recuperación por Cliente
-
- + - - <%# Eval("Marca") %> - - - - <%# Eval("Año", "{0:N2}") %> - - - <%# Eval("Mes", "{0:N2}") %> - - - <%# Eval("Semana", "{0:N2}") %> - - - <%# Eval("Día", "{0:N2}") %> - + + +
-
+
+ + + + + +
+
- Ventas por PS + Compras por Clasificación
-
- + - - <%# Eval("ProductoServicio") %> - - - - <%# Eval("Año", "{0:N2}") %> - - - <%# Eval("Mes", "{0:N2}") %> - - - <%# Eval("Semana", "{0:N2}") %> - - - <%# Eval("Día", "{0:N2}") %> - + + + + +
-
+
- Ventas por Cliente + Compras por Marca
-
- + - - <%# Eval("NombreCliente") %> - - - - <%# Eval("Año", "{0:N2}") %> - - - <%# Eval("Mes", "{0:N2}") %> - - - <%# Eval("Semana", "{0:N2}") %> - - - <%# Eval("Día", "{0:N2}") %> - - - -
-
-
- -
-
-
-
- Ventas por Proveedor -
-
-
- - - - <%# Eval("NombreProveedor") %> - - - - <%# Eval("Año", "{0:N2}") %> - - - <%# Eval("Mes", "{0:N2}") %> - - - <%# Eval("Semana", "{0:N2}") %> - - - <%# Eval("Día", "{0:N2}") %> - + + + + +
@@ -1229,22 +836,175 @@
- +
+
+
+
+
+ Compras por PS +
+
+
+ + + + + + + + + +
+
+
- - - - - - - - - +
+
+
+
+ Compras por Proveedor +
+
+
+ + + + + + + + + +
+
+
+
+
+ +
+
+
+ +
+
+
+ +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ CxP por Sucursal +
+
+
+ + + + + + + + +
+
+
+ +
+
+
+
+ CxP por Proveedor +
+
+
+ + + + + + + + +
+
+
+
+ +
+ +
+
+
+
+ Pagos por Sucursal +
+
+
+ + + + + + + +
+
+
+ +
+
+
+
+ Pagos por Proveedor +
+
+
+ + + + + + + +
+
+
+ +
diff --git a/General/Dashboard.aspx.vb b/General/Dashboard.aspx.vb index 21ba073fa..b3f4a34bc 100644 --- a/General/Dashboard.aspx.vb +++ b/General/Dashboard.aspx.vb @@ -25,8 +25,7 @@ Partial Class General_Dashboard End Sub Private Sub BindDropdown() - ' Actualmente las opciones están definidas en el markup - ' Aquí podrías cargar dinámicamente si lo deseas en el futuro + End Sub Public Overrides Sub VerifyRenderingInServerForm(control As Control) @@ -49,7 +48,7 @@ Partial Class General_Dashboard Select Case opcion Case 1 ' Ingresos - ProcesarDatosIndicadores(ds.Tables("Indicadores")) + IndicadoresIngresos(ds.Tables("Indicadores")) CargarResumenSucursales(ds.Tables("DetalleDia")) CargarVentasMensuales(ds.Tables("DetalleAnualesMes")) @@ -63,79 +62,88 @@ Partial Class General_Dashboard Case 2 ' Recuperación - ' TODO: Implementar carga de indicadores, gráficas y grids para Recuperación + IndicadoresRecuperacionCxc(ds.Tables("CarteraPorSubproyecto"), ds.Tables("RecuperacionPorSubproyecto")) + + CargarCarteraPorSucursal(ds.Tables("CarteraPorSubproyecto")) + CargarCarteraPorVendedor(ds.Tables("CarteraPorVendedor")) + CargarRecuperacionPorSucursal(ds.Tables("RecuperacionPorSubproyecto")) + CargarRecuperacionPorCliente(ds.Tables("RecuperacionPorCliente")) + CargarCxCMensual(ds.Tables("CxCMensual")) Case 3 ' Compras - ' TODO: Implementar carga para Compras + CargarComprasPorClasificacion(ds.Tables("ComprasPorClasificación")) + CargarComprasPorMarca(ds.Tables("ComprasPorMarca")) + CargarComprasPorPS(ds.Tables("ComprasPorPS")) + CargarComprasPorProveedor(ds.Tables("ComprasPorProveedor")) - Case 4 ' Gasto - ' TODO: Implementar carga para Gasto + Case 4 ' Cuentas por Pagar + IndicadoresCxP(ds.Tables("CxPPorSubproyecto"), ds.Tables("PagosPorSubproyecto")) - Case 5 ' Cuentas por Pagar - ' TODO: Implementar carga para CxP + ' Cargar GridViews + CargarCxPPorSucursal(ds.Tables("CxPPorSubproyecto")) + CargarCxPPorProveedor(ds.Tables("CxPPorProveedor")) + CargarPagosPorSucursal(ds.Tables("PagosPorSubproyecto")) + CargarPagosPorProveedor(ds.Tables("PagosPorProveedor")) + CargarCxPMensual(ds.Tables("CxPMensual")) - Case 6 ' Inventario + Case 5 ' Inventario ' TODO: Implementar carga para Inventario - Case 7 ' Utilidad + Case 6 ' Utilidad ' TODO: Implementar carga para Utilidad - Case 8 ' Impuestos + Case 7 ' Impuestos ' TODO: Implementar carga para Impuestos - Case 9 ' CRM + Case 8 ' CRM ' TODO: Implementar carga para CRM - Case 10 ' RH + Case 9 ' RH ' TODO: Implementar carga para RH - Case 11 ' AF + Case 10 ' AF ' TODO: Implementar carga para AF End Select End Sub Protected Sub LnkExportarPDF_Click(sender As Object, e As EventArgs) Handles LnkExportarPDF.Click - DivIndicadoresLeft.InnerHtml &= DivIndicadoresRight.InnerHtml - DivIndicadoresRight.InnerHtml = String.Empty + DivIndicadoresIngresosLeft.InnerHtml &= DivIndicadoresIngresosRight.InnerHtml + DivIndicadoresIngresosRight.InnerHtml = String.Empty pnlDashboard.GenerarReportePDF("Reporte Resumen de Indicadores") End Sub - - Private Sub CargarIndicadores(dt As DataTable) - If dt IsNot Nothing AndAlso dt.Rows.Count > 0 Then - ProcesarDatosIndicadores(dt) - End If - End Sub - - Private Sub ProcesarDatosIndicadores(dt As DataTable) + Private Sub IndicadoresIngresos(dt As DataTable) If dt Is Nothing OrElse dt.Rows.Count = 0 Then Return End If Dim dr As DataRow = dt.Rows(0) - ' Indicador Año - MuestraIndicador(DivIndicadoresLeft, "blue", "fa fa-calendar", "Año Actual", dr("AcumAño").ToString.FormatoNumero(0), "#", "Acumulado", + DivIndicadoresIngresosLeft.InnerHtml = String.Empty + DivIndicadoresIngresosRight.InnerHtml = String.Empty + + ' Indicador Año + MuestraIndicador(DivIndicadoresIngresosLeft, "blue", "fa fa-calendar", "Año Actual", dr("AcumAño").ToString.FormatoNumero(0), "#", "Acumulado", dr("AcumAñoPromedio").ToString.FormatoNumero(0), "#", "Ticket Promedio", dr("AcumAñoContado").ToString.FormatoNumero(0), "#", "Contado", dr("AcumAñoCredito").ToString.FormatoNumero(0), "#", "Crédito") - ' Indicador Mes - MuestraIndicador(DivIndicadoresLeft, "green", "fa fa-calendar-check-o", "Mes Actual", + ' Indicador Mes + MuestraIndicador(DivIndicadoresIngresosLeft, "green", "fa fa-calendar-check-o", "Mes Actual", dr("AcumMes").ToString.FormatoNumero(0), "#", "Acumulado", dr("AcumMesPromedio").ToString.FormatoNumero(0), "#", "Ticket Promedio", dr("AcumMesContado").ToString.FormatoNumero(0), "#", "Contado", dr("AcumMesCredito").ToString.FormatoNumero(0), "#", "Crédito") - ' Indicador Semana - MuestraIndicador(DivIndicadoresRight, "purple", "fa fa-calendar-minus-o", "Semana Actual", + ' Indicador Semana + MuestraIndicador(DivIndicadoresIngresosRight, "purple", "fa fa-calendar-minus-o", "Semana Actual", dr("AcumSemana").ToString.FormatoNumero(0), "#", "Acumulado", dr("AcumSemanaPromedio").ToString.FormatoNumero(0), "#", "Ticket Promedio", dr("AcumSemanaContado").ToString.FormatoNumero(0), "#", "Contado", dr("AcumSemanaCredito").ToString.FormatoNumero(0), "#", "Crédito") - MuestraIndicador(DivIndicadoresRight, "red", "fa fa-sun-o", "Hoy", + MuestraIndicador(DivIndicadoresIngresosRight, "red", "fa fa-sun-o", "Hoy", "0".FormatoNumero(0), "#", "Acumulado", "0".FormatoNumero(0), "#", "Ticket Promedio", "0".FormatoNumero(0), "#", "Contado", @@ -143,6 +151,133 @@ Partial Class General_Dashboard End Sub + Private Sub IndicadoresRecuperacionCxc(dtCartera As DataTable, dtRecuperacion As DataTable) + If dtCartera Is Nothing OrElse dtCartera.Rows.Count = 0 Then Return + If dtRecuperacion Is Nothing OrElse dtRecuperacion.Rows.Count = 0 Then Return + + ' Calcular totales para Cartera Vencida + Dim totalVencido As Decimal = 0 + Dim totalPorVencer As Decimal = 0 + Dim totalCxC As Decimal = 0 + Dim maxRotacion As Decimal = 0 + + For Each row As DataRow In dtCartera.Rows + totalVencido += If(IsDBNull(row("Vencido")), 0D, row("Vencido")).ToString.ToDecimal() + totalPorVencer += If(IsDBNull(row("Por Vencer")), 0D, row("Por Vencer")).ToString.ToDecimal() + If dtCartera.Columns.Contains("RotacionCartera") AndAlso Not IsDBNull(row("RotacionCartera")) Then + Dim rotacion = Convert.ToDecimal(row("RotacionCartera")) + If rotacion > maxRotacion Then maxRotacion = rotacion + End If + + Next + + totalCxC = totalVencido + totalPorVencer + + ' Calcular total para Recuperación + Dim totalRecuperado As Decimal = 0 + For Each row As DataRow In dtRecuperacion.Rows + totalRecuperado += If(IsDBNull(row("Recuperado")), 0D, row("Recuperado")).ToString.ToDecimal() + Next + + DivIndicadoresRecuperacionLeft.InnerHtml = "" + DivIndicadoresRecuperacionRight.InnerHtml = "" + + ' Indicador Cartera Vencida + MuestraIndicador(DivIndicadoresRecuperacionLeft, "blue", "fa fa-calendar", "Cartera Vencida", + totalCxC.ToString.FormatoNumero(0), "#", "CxC", + totalVencido.ToString.FormatoNumero(0), "#", "Vencido", + totalPorVencer.ToString.FormatoNumero(0), "#", "Por Vencer") + + 'Indicador KPI Recuperación + MuestraIndicadorKPI(DivIndicadoresRecuperacionLeft, "purple", "fa fa-usd", + "Recuperación", + totalRecuperado.ToString.FormatoNumero(0), + "#", + "Recuperación") + + Dim factorRecuperacion As Decimal = 0 + If totalCxC > 0 Then + factorRecuperacion = (totalRecuperado / totalCxC) + End If + + MuestraIndicadorKPI(DivIndicadoresRecuperacionRight, "green", "fa fa-fa-percent", + "Factor Recuperación", + factorRecuperacion.ToString("N2") & "%", + "#", + "Porcentaje de cartera recuperada") + + MuestraIndicadorKPI(DivIndicadoresRecuperacionRight, "red", "fa fa-refresh", + "Rotación Cartera", + maxRotacion.ToString("N1"), + "#", + "Máxima rotación de cartera entre sucursales") + + End Sub + + Private Sub IndicadoresCxP(dtCxP As DataTable, dtPagos As DataTable) + If dtCxP Is Nothing OrElse dtCxP.Rows.Count = 0 Then Return + If dtPagos Is Nothing OrElse dtPagos.Rows.Count = 0 Then Return + + ' Calcular totales para CxP + Dim totalVencido As Decimal = 0 + Dim totalPorVencer As Decimal = 0 + Dim totalCxP As Decimal = 0 + Dim maxRotacion As Decimal = 0 + + For Each row As DataRow In dtCxP.Rows + totalVencido += Convert.ToDecimal(If(IsDBNull(row("Vencido")), 0D, row("Vencido"))) + totalPorVencer += Convert.ToDecimal(If(IsDBNull(row("Por Vencer")), 0D, row("Por Vencer"))) + + ' Obtener rotación máxima + If dtCxP.Columns.Contains("RotacionCartera") AndAlso Not IsDBNull(row("RotacionCartera")) Then + Dim rotacion = Convert.ToDecimal(row("RotacionCartera")) + If rotacion > maxRotacion Then maxRotacion = rotacion + End If + Next + totalCxP = totalVencido + totalPorVencer + + ' Calcular total pagado + Dim totalPagado As Decimal = 0 + For Each row As DataRow In dtPagos.Rows + totalPagado += Convert.ToDecimal(If(IsDBNull(row("Recuperado")), 0D, row("Recuperado"))) + Next + + DivIndicadoresCxPLeft.InnerHtml = "" + DivIndicadoresRecuperacionRight.InnerHtml = "" + + ' Indicador CxP + MuestraIndicador(DivIndicadoresCxPLeft, "blue", "fa fa-calendar", "Cuentas por Pagar", + totalCxP.ToString.FormatoNumero(0), "#", "Total CxP", + totalVencido.ToString.FormatoNumero(0), "#", "Vencido", + totalPorVencer.ToString.FormatoNumero(0), "#", "Por Vencer") + + ' KPI Pagado + MuestraIndicadorKPI(DivIndicadoresCxPLeft, "purple", "fa fa-usd", + "Total Pagado", + totalPagado.ToString.FormatoNumero(0), + "#", + "Total pagado a proveedores") + + ' KPI Factor CxP vs Pagado + Dim factorPago As Decimal = 0 + If totalCxP > 0 Then + factorPago = (totalPagado / totalCxP) * 100 + End If + + MuestraIndicadorKPI(DivIndicadoresCxPRight, "green", "fa fa-percent", + "Factor Pago", + factorPago.ToString("N2") & "%", + "#", + "Porcentaje de CxP pagado") + + ' KPI Rotación de Cartera + MuestraIndicadorKPI(DivIndicadoresCxPRight, "red", "fa fa-refresh", + "Rotación CxP", + maxRotacion.ToString("N1") & " días", + "#", + "Máxima rotación de CxP entre sucursales") + End Sub + Private Sub CargarVentasMensuales(dt As DataTable) If dt Is Nothing OrElse dt.Rows.Count = 0 Then Return @@ -480,7 +615,420 @@ Partial Class General_Dashboard gvVentasPorProveedor.DataBind() End Sub + Private Sub CargarCarteraPorSucursal(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then + Return + End If + ' Crear DataTable con estructura necesaria + Dim dtGrid = New DataTable() + dtGrid.Columns.Add("Sucursal", GetType(String)) + dtGrid.Columns.Add("TotalCxC", GetType(Decimal)) + dtGrid.Columns.Add("Vencido", GetType(Decimal)) + dtGrid.Columns.Add("PorVencer", GetType(Decimal)) + + For Each row As DataRow In dt.Rows + Dim vencido = (If(IsDBNull(row("Vencido")), 0D, row("Vencido"))).ToString.ToDecimal() + Dim porVencer = (If(IsDBNull(row("Por Vencer")), 0D, row("Por Vencer"))).ToString.ToDecimal() + Dim totalCxC = vencido + porVencer + + dtGrid.Rows.Add( + row("Sucursal").ToString(), + totalCxC, + vencido, + porVencer + ) + Next + + gvCarteraPorSucursal.DataSource = dtGrid + gvCarteraPorSucursal.DataBind() + End Sub + + Private Sub CargarCarteraPorVendedor(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then + Return + End If + + ' Crear DataTable con estructura necesaria + Dim dtGrid = New DataTable() + dtGrid.Columns.Add("Vendedor", GetType(String)) + dtGrid.Columns.Add("TotalCxC", GetType(Decimal)) + dtGrid.Columns.Add("Vencido", GetType(Decimal)) + dtGrid.Columns.Add("PorVencer", GetType(Decimal)) + + For Each row As DataRow In dt.Rows + Dim vencido = Convert.ToDecimal(If(IsDBNull(row("Vencido")), 0D, row("Vencido"))) + Dim porVencer = Convert.ToDecimal(If(IsDBNull(row("Por Vencer")), 0D, row("Por Vencer"))) + Dim totalCxC = vencido + porVencer + + dtGrid.Rows.Add( + row("Vendedor").ToString(), + totalCxC, + vencido, + porVencer + ) + Next + + gvCarteraPorVendedor.DataSource = dtGrid + gvCarteraPorVendedor.DataBind() + End Sub + + Private Sub CargarCxCMensual(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then + Return + End If + + ' Lista de meses en español + Dim mesesOrdenados As New List(Of String) From { + "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", + "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" + } + + ' Obtener años distintos de forma segura + Dim años As New List(Of Integer) + For Each row As DataRow In dt.Rows + If Not IsDBNull(row("Año")) Then + Dim añoValue As String = row("Año").ToString() + Dim añoInt As Integer + If Integer.TryParse(añoValue, añoInt) Then + If Not años.Contains(añoInt) Then + años.Add(añoInt) + End If + End If + End If + Next + años = años.OrderBy(Function(y) y).ToList() + + Dim seriesData As New List(Of Dictionary(Of String, Object)) + + For Each año In años + ' Filtrar datos para este año + Dim añoData = dt.AsEnumerable() _ + .Where(Function(r) Not IsDBNull(r("Año")) AndAlso + Integer.TryParse(r("Año").ToString(), Nothing) AndAlso + Convert.ToInt32(r("Año")) = año) _ + .FirstOrDefault() + + If añoData IsNot Nothing Then + Dim dataPoints As New List(Of Object()) + + ' Obtener valores para cada mes + For i = 0 To mesesOrdenados.Count - 1 + Dim mes = mesesOrdenados(i) + If dt.Columns.Contains(mes) Then + Dim valor As Decimal = 0D + If Not IsDBNull(añoData(mes)) Then + ' Conversión segura a decimal + Decimal.TryParse(añoData(mes).ToString(), valor) + End If + dataPoints.Add({i, valor}) + End If + Next + + seriesData.Add(New Dictionary(Of String, Object) From { + {"name", año.ToString}, + {"data", dataPoints}, + {"color", GetColorForYear(años.IndexOf(año))} + }) + End If + Next + + ' Configuración de la gráfica (igual que la de ventas) + Dim chartOptions = New With { + .chart = New With {.type = "line"}, + .title = New With {.text = "CxC Mensual"}, + .xAxis = New With { + .type = "category", + .categories = mesesOrdenados, + .title = New With {.text = "Mes"} + }, + .yAxis = New With { + .title = New With {.text = "Monto CxC (MXN)"}, + .labels = New With {.format = "${value:,.0f}"} + }, + .tooltip = New With { + .headerFormat = "{series.name}
", + .pointFormat = "Mes: {point.category}
CxC: ${point.y:,.2f} MXN" + }, + .plotOptions = New With { + .line = New With { + .dataLabels = New With {.enabled = False}, + .enableMouseTracking = True + } + }, + .series = seriesData + } + + Dim script = $" + Highcharts.chart('divCxCMensual', {JsonConvert.SerializeObject(chartOptions)}); + " + ScriptManager.RegisterStartupScript(Me, Me.GetType(), "graficaCxC", script, True) + End Sub + + Private Sub CargarRecuperacionPorSucursal(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then + Return + End If + + ' Renombrar columna para mejor presentación + If dt.Columns.Contains("P. Días recuperodo vencidos") Then + dt.Columns("P. Días recuperodo vencidos").ColumnName = "PromedioDiasRecuperacion" + End If + + gvRecuperacionPorSucursal.DataSource = dt + gvRecuperacionPorSucursal.DataBind() + End Sub + + Private Sub CargarRecuperacionPorCliente(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then + Return + End If + + ' Crear DataTable con estructura necesaria + Dim dtGrid = New DataTable() + dtGrid.Columns.Add("Cliente", GetType(String)) + dtGrid.Columns.Add("Recuperado", GetType(Decimal)) + dtGrid.Columns.Add("PromedioDiasRecuperacion", GetType(Decimal)) + + For Each row As DataRow In dt.Rows + dtGrid.Rows.Add( + row("Nombre").ToString(), ' Asegurar que la columna se llama "Nombre" + Convert.ToDecimal(If(IsDBNull(row("Recuperado")), 0D, row("Recuperado"))), + Convert.ToDecimal(If(IsDBNull(row("P. Días recuperodo vencidos")), 0D, row("P. Días recuperodo vencidos"))) + ) + Next + + gvRecuperacionPorCliente.DataSource = dtGrid + gvRecuperacionPorCliente.DataBind() + End Sub + + Private Sub CargarComprasPorClasificacion(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then + Return + End If + + gvComprasPorClasificacion.DataSource = dt + gvComprasPorClasificacion.DataBind() + End Sub + + Private Sub CargarComprasPorMarca(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then + Return + End If + + gvComprasPorMarca.DataSource = dt + gvComprasPorMarca.DataBind() + End Sub + + Private Sub CargarComprasPorPS(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then + Return + End If + + gvComprasPorPS.DataSource = dt + gvComprasPorPS.DataBind() + End Sub + + Private Sub CargarComprasPorProveedor(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then + Return + End If + + gvComprasPorProveedor.DataSource = dt + gvComprasPorProveedor.DataBind() + End Sub + + ' Métodos para cargar los GridViews + Private Sub CargarCxPPorSucursal(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then Return + + ' Crear un nuevo DataTable con las columnas necesarias + Dim dtGrid = New DataTable() + dtGrid.Columns.Add("Sucursal", GetType(String)) + dtGrid.Columns.Add("Vencido", GetType(Decimal)) + dtGrid.Columns.Add("PorVencer", GetType(Decimal)) + dtGrid.Columns.Add("Total", GetType(Decimal)) ' Columna Total requerida + + ' Copiar datos y calcular Total + For Each row As DataRow In dt.Rows + Dim vencido = Convert.ToDecimal(If(IsDBNull(row("Vencido")), 0D, row("Vencido"))) + Dim porVencer = Convert.ToDecimal(If(IsDBNull(row("Por Vencer")) OrElse Not dt.Columns.Contains("Por Vencer"), 0D, row("Por Vencer"))) + Dim total = vencido + porVencer + + dtGrid.Rows.Add( + row("Sucursal").ToString(), + vencido, + porVencer, + total + ) + Next + + gvCxPPorSucursal.DataSource = dtGrid + gvCxPPorSucursal.DataBind() + End Sub + + Private Sub CargarCxPPorProveedor(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then Return + + ' Crear un nuevo DataTable con las columnas necesarias + Dim dtGrid = New DataTable() + dtGrid.Columns.Add("RazonSocial", GetType(String)) + dtGrid.Columns.Add("Vencido", GetType(Decimal)) + dtGrid.Columns.Add("PorVencer", GetType(Decimal)) + dtGrid.Columns.Add("Total", GetType(Decimal)) ' Columna Total requerida + + ' Copiar datos y calcular Total + For Each row As DataRow In dt.Rows + Dim vencido = Convert.ToDecimal(If(IsDBNull(row("Vencido")), 0D, row("Vencido"))) + Dim porVencer = Convert.ToDecimal(If(IsDBNull(row("Por Vencer")) OrElse Not dt.Columns.Contains("Por Vencer"), 0D, row("Por Vencer"))) + Dim total = vencido + porVencer + + dtGrid.Rows.Add( + row("RazonSocial").ToString(), + vencido, + porVencer, + total + ) + Next + + gvCxPPorProveedor.DataSource = dtGrid + gvCxPPorProveedor.DataBind() + End Sub + + Private Sub CargarPagosPorSucursal(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then Return + + ' Crear nuevo DataTable con nombres de columnas consistentes + Dim dtGrid = New DataTable() + dtGrid.Columns.Add("Sucursal", GetType(String)) + dtGrid.Columns.Add("Recuperado", GetType(Decimal)) + dtGrid.Columns.Add("PromedioDias", GetType(Decimal)) + + For Each row As DataRow In dt.Rows + dtGrid.Rows.Add( + row("Sucursal").ToString(), + Convert.ToDecimal(If(IsDBNull(row("Recuperado")), 0D, row("Recuperado"))), + Convert.ToDecimal(If(IsDBNull(row("P. Días recuperodo vencidos")), 0D, row("P. Días recuperodo vencidos"))) + ) + Next + + gvPagosPorSucursal.DataSource = dtGrid + gvPagosPorSucursal.DataBind() + End Sub + + Private Sub CargarPagosPorProveedor(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then Return + + ' Crear nuevo DataTable con nombres de columnas consistentes + Dim dtGrid = New DataTable() + dtGrid.Columns.Add("RazonSocial", GetType(String)) + dtGrid.Columns.Add("Recuperado", GetType(Decimal)) + dtGrid.Columns.Add("PromedioDias", GetType(Decimal)) + + For Each row As DataRow In dt.Rows + dtGrid.Rows.Add( + row("RazonSocial").ToString(), + Convert.ToDecimal(If(IsDBNull(row("Recuperado")), 0D, row("Recuperado"))), + Convert.ToDecimal(If(IsDBNull(row("P. Días recuperodo vencidos")), 0D, row("P. Días recuperodo vencidos"))) + ) + Next + + gvPagosPorProveedor.DataSource = dtGrid + gvPagosPorProveedor.DataBind() + End Sub + + Private Sub CargarCxPMensual(dt As DataTable) + If dt Is Nothing OrElse dt.Rows.Count = 0 Then + Return + End If + + ' Lista de meses en español + Dim mesesOrdenados As New List(Of String) From { + "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", + "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" + } + + ' Obtener años distintos de forma segura + Dim años As New List(Of Integer) + For Each row As DataRow In dt.Rows + If Not IsDBNull(row("Año")) Then + Dim añoValue As String = row("Año").ToString() + Dim añoInt As Integer + If Integer.TryParse(añoValue, añoInt) Then + If Not años.Contains(añoInt) Then + años.Add(añoInt) + End If + End If + End If + Next + años = años.OrderBy(Function(y) y).ToList() + + Dim seriesData As New List(Of Dictionary(Of String, Object)) + + For Each año In años + ' Filtrar datos para este año + Dim añoData = dt.AsEnumerable() _ + .Where(Function(r) Not IsDBNull(r("Año")) AndAlso + Integer.TryParse(r("Año").ToString(), Nothing) AndAlso + Convert.ToInt32(r("Año")) = año) _ + .FirstOrDefault() + + If añoData IsNot Nothing Then + Dim dataPoints As New List(Of Object()) + + ' Obtener valores para cada mes + For i = 0 To mesesOrdenados.Count - 1 + Dim mes = mesesOrdenados(i) + If dt.Columns.Contains(mes) Then + Dim valor As Decimal = 0D + If Not IsDBNull(añoData(mes)) Then + ' Conversión segura a decimal + Decimal.TryParse(añoData(mes).ToString(), valor) + End If + ' Usar el índice del mes (0-11) como posición X + dataPoints.Add({i, valor}) + End If + Next + + seriesData.Add(New Dictionary(Of String, Object) From { + {"name", año.ToString}, + {"data", dataPoints}, + {"color", GetColorForYear(años.IndexOf(año))} + }) + End If + Next + + ' Configuración de la gráfica (mismo estilo que CxC) + Dim chartOptions = New With { + .chart = New With {.type = "line"}, + .title = New With {.text = "Evolución de Cuentas por Pagar (CxP) Mensual"}, + .xAxis = New With { + .type = "category", + .categories = mesesOrdenados, + .title = New With {.text = "Mes"} + }, + .yAxis = New With { + .title = New With {.text = "Monto CxP (MXN)"}, + .labels = New With {.format = "${value:,.0f}"} + }, + .tooltip = New With { + .headerFormat = "{series.name}
", + .pointFormat = "Mes: {point.category}
CxP: ${point.y:,.2f} MXN" + }, + .plotOptions = New With { + .line = New With { + .dataLabels = New With {.enabled = False}, + .enableMouseTracking = True + } + }, + .series = seriesData + } + + Dim script = $" + Highcharts.chart('divCxPMensual', {JsonConvert.SerializeObject(chartOptions)}); + " + ScriptManager.RegisterStartupScript(Me, Me.GetType(), "graficaCxP", script, True) + End Sub Private Function ObtenerMesesOrdenados() As List(Of String) Return CultureInfo.CurrentCulture.DateTimeFormat.MonthNames _ @@ -536,4 +1084,38 @@ Partial Class General_Dashboard DIV.InnerHtml = htmldiv.ToString End Sub + ' Método para mostrar el KPI (Agrégalo en tu clase) + Private Sub MuestraIndicadorKPI(DIV As HtmlGenericControl, Color As String, Icono As String, Titulo As String, Valor As String, CL1 As String, Tooltip As String) + Dim htmldiv As New StringBuilder + + + ' Estructura del contenedor principal + htmldiv.AppendFormat( + "{0}
" & + "
" & ' Contenedor relativo + "
", + DIV.InnerHtml, Color, Icono + ) + + ' Contenido principal + htmldiv.Append("
") + htmldiv.AppendFormat( + "
{1}
", + Tooltip, Titulo + ) + htmldiv.AppendFormat("
{0}
", Valor) + htmldiv.Append("
") + + + htmldiv.AppendFormat( + "" & + "Ver Más", + CL1 + ) + + htmldiv.Append("
") ' Cierre de dashboard-stat y col + + DIV.InnerHtml = htmldiv.ToString + End Sub + End Class diff --git a/Inicio.aspx.vb b/Inicio.aspx.vb index 570085ae2..65749abba 100644 --- a/Inicio.aspx.vb +++ b/Inicio.aspx.vb @@ -1665,7 +1665,7 @@ Partial Class Inicio Dim FechaI As Date = txtFechaInicioSMS.Text.ToDate ' Now.FirstDayOfMonth Dim FechaF As Date = txtFechaFinSMS.Text.ToDate 'Now.LastDayOfMonth - If Gral.GetSMSIndicadores(Opcion, FechaI, FechaF, UsuarioActual.CveUsuario, CveVendedor, CveGerenteVendedor, CveUsuarioTecnico, UsuarioActual.CveEmpresa) Then + If Gral.GetSMSIndicadores(Opcion, FechaI, FechaF, UsuarioActual.CveUsuario, CveVendedor, CveUsuarioTecnico, UsuarioActual.CveEmpresa) Then ds = Gral.DataSetResultados End If '0-ventas totales, 1-comisiones totales, 2-medicos sin consumo, 3-top10medicos, 4-top5marcas, 5-num pacientes diff --git a/OP/OP.aspx b/OP/OP.aspx index dfdc3300f..e173c9a42 100644 --- a/OP/OP.aspx +++ b/OP/OP.aspx @@ -310,18 +310,16 @@ cursor: pointer; } /* Alinear celda y contenido a la derecha */ -.celda-derecha { - text-align: right !important; - -} - -.txt-merma { - /* Ancho reducido al 50% */ - margin-left: 30px !important; /* Mueve el TextBox a la derecha dentro de la celda */ - display: block !important; /* Permite que margin-left:auto funcione */ - /* Alinea el texto interno a la derecha */ -} + .celda-derecha { + text-align: right !important; + } + .txt-merma { + /* Ancho reducido al 50% */ + margin-left: 30px !important; /* Mueve el TextBox a la derecha dentro de la celda */ + display: block !important; /* Permite que margin-left:auto funcione */ + /* Alinea el texto interno a la derecha */ + } @@ -364,16 +362,16 @@
- +
- +
@@ -428,7 +426,7 @@ ControlToValidate="TxtDescripcion" ErrorMessage="Descripción requerida" Display="None" - CssClass="text-danger" + CssClass="text-danger" ValidationGroup="GrpGuardar" />
@@ -437,7 +435,7 @@
- +
@@ -471,13 +469,13 @@
- -
- -
+ +
+ +
+ onchange="validarCantidad(this)" + ItemStyle-HorizontalAlign="Right" /> @@ -872,18 +870,17 @@ CssClass="table table-striped table-hover" GridLines="None" Width="100%"> - + + onchange="validarCantidad(this)" /> @@ -947,15 +944,14 @@ + data-original='<%# Eval("Cantidad")%>' /> - + diff --git a/OP/OP.aspx.vb b/OP/OP.aspx.vb index 7e1cee9f6..c0166cd12 100644 --- a/OP/OP.aspx.vb +++ b/OP/OP.aspx.vb @@ -125,6 +125,7 @@ Partial Class OP_OP BtnCancelarOP.Visible = (CveOP > 0 AndAlso TipoEstatus <> 3 AndAlso TipoEstatus <> 4) End Sub +#Region "Metodos" Private Sub CreaPS() DtPS = New DataTable() DtPS.Columns.Add("Tipo", GetType(String)) ' Producto, MP, MO, CI @@ -247,7 +248,9 @@ Partial Class OP_OP UpBtns.Update() UpModalCancelar.Update() End Sub +#End Region +#Region "Cargar" Private Sub CargaDatos() If CveOP > 0 Then Dim ObjOP As New ClsOP() @@ -367,7 +370,9 @@ Partial Class OP_OP DdlPS.ddl.Items.Insert(0, New ListItem("Seleccione el Producto", "-1")) End If End Sub +#End Region +#Region "Producto" Protected Sub BtnAgregarProducto_Click(sender As Object, e As EventArgs) Handles BtnAgregarProducto.Click If DdlPS.SelectedValue = "-1" Then Exit Sub @@ -480,33 +485,16 @@ Partial Class OP_OP Next End Sub + Protected Sub GvProductos_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GvProductos.RowDataBound If e.Row.RowType = DataControlRowType.DataRow Then Dim btnEliminar As LinkButton = DirectCast(e.Row.FindControl("BtnEliminar"), LinkButton) btnEliminar.Visible = (TipoEstatus <> 3) End If End Sub +#End Region - Protected Sub LnkSolicitarMP_Click(sender As Object, e As EventArgs) - ' Cargar almacenes - DdlAlmacenOrigenMP.DataSource = GlobalDTAlmacen(UsuarioActual.CveEmpresa).FiltraParametros("CveTipoAlmacen = 1") - DdlAlmacenOrigenMP.DataBind() - DdlAlmacenDestinoMP.DataSource = GlobalDTAlmacen(UsuarioActual.CveEmpresa).FiltraParametros("CveTipoAlmacen = 28") - DdlAlmacenDestinoMP.DataBind() - - GvMPAgregados.DataKeyNames = New String() {"CvePSMateriaPrima", "CveUMMateriaPrima"} - - ' Filtrar MP no surtida - Dim DtMPFaltante As DataTable = DtMP.FiltraParametros("Surtido = 0").Copy() - GvMPAgregados.DataSource = DtMPFaltante - GvMPAgregados.DataBind() - - - ' Mostrar modal - RegistraScript("$('#DVModalSolicitarMP').modal('show');") - UpModalMP.Update() - End Sub - +#Region "Simular MP" Protected Sub BtnSimularMP_Click(sender As Object, e As EventArgs) If CveOP <> -1 Then Exit Sub If DdlPS.SelectedValue = "-1" Then Exit Sub @@ -664,7 +652,28 @@ Partial Class OP_OP Return ObjOP.DtResultados.Copy() End Function +#End Region +#Region "Solicitar MP" + Protected Sub LnkSolicitarMP_Click(sender As Object, e As EventArgs) + ' Cargar almacenes + DdlAlmacenOrigenMP.DataSource = GlobalDTAlmacen(UsuarioActual.CveEmpresa).FiltraParametros("CveTipoAlmacen = 1") + DdlAlmacenOrigenMP.DataBind() + DdlAlmacenDestinoMP.DataSource = GlobalDTAlmacen(UsuarioActual.CveEmpresa).FiltraParametros("CveTipoAlmacen = 28") + DdlAlmacenDestinoMP.DataBind() + + GvMPAgregados.DataKeyNames = New String() {"CvePSMateriaPrima", "CveUMMateriaPrima"} + + ' Filtrar MP no surtida + Dim DtMPFaltante As DataTable = DtMP.FiltraParametros("Surtido = 0").Copy() + GvMPAgregados.DataSource = DtMPFaltante + GvMPAgregados.DataBind() + + + ' Mostrar modal + RegistraScript("$('#DVModalSolicitarMP').modal('show');") + UpModalMP.Update() + End Sub Protected Sub BtnGuardarSolicitudMP_Click(sender As Object, e As EventArgs) Dim CveTraspasoSolicitud As Integer = -1 @@ -772,6 +781,9 @@ Partial Class OP_OP ObjInventario.Dispose() End Sub +#End Region + +#Region "Guardar OP" Protected Sub BtnGuardarOP_Click(sender As Object, e As EventArgs) ' Validaciones básicas @@ -930,6 +942,8 @@ Partial Class OP_OP End If End Sub +#End Region + #Region "Cancelar" Protected Sub BtnCancelarOP_Click(sender As Object, e As EventArgs) ' Cargar almacenes From fb67bcd3c1862798c3879064c9badb3022ba2102 Mon Sep 17 00:00:00 2001 From: JPerez Date: Sat, 7 Jun 2025 14:15:07 -0700 Subject: [PATCH 05/11] --generacion de PA desde cotizacion --- Ventas/Ventas.aspx.vb | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/Ventas/Ventas.aspx.vb b/Ventas/Ventas.aspx.vb index 2c255cd97..810d41a9e 100644 --- a/Ventas/Ventas.aspx.vb +++ b/Ventas/Ventas.aspx.vb @@ -8119,6 +8119,8 @@ Partial Class Ventas If CreditoDispo < 0 Then BtnsFacturar.Visible = False BtnGenerarRemision.Visible = False + + TieneBloqueoPorCreditoVencimiento = 1 Alert("El límite de crédito se ha excedido", TipoMensaje.MsgAdvertencia) End If End If @@ -8133,9 +8135,7 @@ Partial Class Ventas BtnGenerarRemision.Visible = False Alert(OpcionMsg, TipoMensaje.MsgAdvertencia) - If UsuarioActual.Empresa.Funcionalidad(531) = "1" AndAlso ClienteEsDistribuidor AndAlso Opcion.Contiene(2, 3) Then - TieneBloqueoPorCreditoVencimiento = 1 - End If + TieneBloqueoPorCreditoVencimiento = 1 End If End If End If @@ -8439,6 +8439,12 @@ Partial Class Ventas End If + 'SI ES COTIZACION, PERMITIR CREAR UN DOCUMENTO NUEVO TIPO "PA" + If DdlTipoComprobante.SelectedValue = "Cot" AndAlso UsuarioActual.Empresa.Funcionalidad(595) = "1" AndAlso TieneBloqueoPorCreditoVencimiento = 1 Then + BtnGeneraAutorizacion.Visible = True + UpFacturar.Update() + End If + End Sub @@ -22102,6 +22108,20 @@ Partial Class Ventas End If End If + 'SI ES FACTURACION DE COTIZACION Y REQUIERE AUTORIZACION, SOLO DEBE PERMITIR ESTA + If UsuarioActual.Empresa.Funcionalidad(595) = "1" AndAlso Request("CveCotizacion") IsNot Nothing AndAlso Request("CveCotizacion").ToString().ToEntero() > 0 AndAlso TieneBloqueoPorAutorizacion = 1 Then + DdlTipoComprobante.Items.Remove(DdlTipoComprobante.Items.FindByValue("Ing")) + DdlTipoComprobante.Items.Remove(DdlTipoComprobante.Items.FindByValue("Egs")) + DdlTipoComprobante.Items.Remove(DdlTipoComprobante.Items.FindByValue("Cot")) + DdlTipoComprobante.Items.Remove(DdlTipoComprobante.Items.FindByValue("Dev")) + + DdlTipoComprobante.SelectedValueExistInsert("PA", "Autorización") + DdlTipoComprobante.SelectedValue = "PA" + + BtnCrearApartirDe.Visible = False + UpFacturar.Update() + End If + '[IPP]: FALTA CONFIGURAR Y DAR PERMISO A TODOS LOS QUE TENGAN ACCESO A VENTAS ''Puede remisionar @@ -35984,7 +36004,7 @@ Partial Class Ventas #Region "GENERAR AUTORIZACIÓN" Protected Sub BtnGeneraAutorizacion_Click(sender As Object, e As EventArgs) - If DdlTipoComprobante.SelectedValue.Contiene("Ped") Then + If DdlTipoComprobante.SelectedValue.Contiene("Ped", "Cot") Then EmitirDocumentoNuevo("PA") End If End Sub From 2da0b5b0095ace063d77df4d83a3dbf86a4c6565 Mon Sep 17 00:00:00 2001 From: JPerez Date: Mon, 9 Jun 2025 15:12:13 -0700 Subject: [PATCH 06/11] --FIX ajuste por saldo al aplicar RNC por concepto --- Ventas/Ventas.aspx | 2 +- Ventas/Ventas.aspx.vb | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Ventas/Ventas.aspx b/Ventas/Ventas.aspx index 97640280d..390e804f4 100644 --- a/Ventas/Ventas.aspx +++ b/Ventas/Ventas.aspx @@ -7699,7 +7699,7 @@
+ DataKeyNames="CveVenta,CveVentaDetalleRNC,CvePS,PU,PorcentajeIVA,Saldo" CssClass="table table-striped table-advance table-hover Widthall mysmallbtn" GridLines="None"> diff --git a/Ventas/Ventas.aspx.vb b/Ventas/Ventas.aspx.vb index 810d41a9e..bed1c3e60 100644 --- a/Ventas/Ventas.aspx.vb +++ b/Ventas/Ventas.aspx.vb @@ -36698,10 +36698,15 @@ Partial Class Ventas Dim ImporteIVA As Decimal = (TotalCalculableImpuestos * PorcentajeIVA).RoundSQL(2) Dim TotalRNCDetalle As Decimal = (TotalCalculableImpuestos + ImporteIVA) + Dim Saldo As Decimal = GvRow.DataKey("Saldo").ToDecimal() + + 'AJUSTAR SALDO SI EL TOTAL ES MAYOR + If TotalRNCDetalle > Saldo Then + TotalRNCDetalle = Saldo + End If TotalRNC += TotalRNCDetalle - End If End If From 648623fd6f03e5207bd9f381f67c0f7abe0924ca Mon Sep 17 00:00:00 2001 From: JPerez Date: Mon, 9 Jun 2025 16:29:44 -0700 Subject: [PATCH 07/11] --FIX ajuste de 1 peso en RNC --- Ventas/Ventas.aspx.vb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Ventas/Ventas.aspx.vb b/Ventas/Ventas.aspx.vb index bed1c3e60..7686c59d3 100644 --- a/Ventas/Ventas.aspx.vb +++ b/Ventas/Ventas.aspx.vb @@ -30731,7 +30731,7 @@ Partial Class Ventas If UsuarioActual.Empresa.Funcionalidad(531) = "1" Then Dim ObjMovtos As New ClsMovimientos() If ObjMovtos.GetAnticiposNCIxCCliente(CveCliente, CveMoneda:=-1) Then - DtNC = ObjMovtos.DtResultados.FiltraParametros("Tipo = 'RNC' AND CveVenta > 0 and Saldo > 0", "Moneda,Fecha,Folio") + DtNC = ObjMovtos.DtResultados.FiltraParametros("Tipo = 'RNC' AND CveVenta > 0 and Saldo > 1", "Moneda,Fecha,Folio") End If ObjMovtos.Dispose() @@ -30835,7 +30835,7 @@ Partial Class Ventas If UsuarioActual.Empresa.Funcionalidad(531) = "1" Then Dim ObjMovtos As New ClsMovimientos() If ObjMovtos.GetAnticiposNCIxCCliente(CveCliente, CveMoneda:=-1) Then - DtNC = ObjMovtos.DtResultados.FiltraParametros("Tipo = 'RNC' AND CveVenta > 0 and Saldo > 0", "Moneda,Fecha,Folio") + DtNC = ObjMovtos.DtResultados.FiltraParametros("Tipo = 'RNC' AND CveVenta > 0 and Saldo > 1", "Moneda,Fecha,Folio") End If ObjMovtos.Dispose() From 3dfc7afab91a8577b6f4481f953bc374fb8433c5 Mon Sep 17 00:00:00 2001 From: JPerez Date: Tue, 10 Jun 2025 12:54:41 -0700 Subject: [PATCH 08/11] --FIX validacion de estatus de cobranza al editar remision, recargar info al cobrar --- Ventas/PVCobranza.aspx.vb | 157 +++++++++++++++++++++----------------- Ventas/Ventas.aspx.vb | 13 ++++ 2 files changed, 100 insertions(+), 70 deletions(-) diff --git a/Ventas/PVCobranza.aspx.vb b/Ventas/PVCobranza.aspx.vb index 835e0e09b..167f6a4db 100644 --- a/Ventas/PVCobranza.aspx.vb +++ b/Ventas/PVCobranza.aspx.vb @@ -500,82 +500,99 @@ Partial Class Ventas_PVCobranza Dim GvRow As GridViewRow = DirectCast(ImgBtn.BindingContainer, GridViewRow) Dim TieneError As Boolean = False - Dim CveVenta As Integer = e.CommandArgument.ToString.ToEntero - Dim CondicionesPagoContado As Boolean = GvRow.DataKey("CondicionesPago") = "0" - Dim ObjVentas As New ClsVentas - ObjVentas.IniciaTransacSQL() - - Try - If Not ObjVentas.UpdateAsignaVentaCobranza(CveVenta, 1, UsuarioActual.CveUsuario, -1, "", Now) Then + Dim CveVenta As Integer = e.CommandArgument.ToString.ToEntero + + Dim RowVenta As DataRow = Nothing + + Using ObjVta As New ClsVentas + If ObjVta.GetVenta(CveVenta, UsuarioActual.CveEmpresa) Then + RowVenta = ObjVta.DtResultados.Copy().Rows(0) + End If + End Using + + If RowVenta IsNot Nothing Then + Dim ObjVentas As New ClsVentas + ObjVentas.IniciaTransacSQL() + + Try + If Not ObjVentas.UpdateAsignaVentaCobranza(CveVenta, 1, UsuarioActual.CveUsuario, -1, "", Now) Then + TieneError = True + End If + HdnCveVenta.Value = CveVenta.ToString + + Dim Saldo As Decimal = RowVenta("Saldo").ToString().ToDecimal() + Dim CveFormaPago33 As String = RowVenta("CveFormaPago33").ToString() + + HdnCveCliente.Value = RowVenta("CveCliente").ToString() + TxtImporteContado.Text = Saldo.FormatoNumero + HdnTotal.Value = Saldo.ToString() + TxtImporteEfectivo.Focus() + LtlNombre.Text = RowVenta("AtencionA").ToString() + LtlFolio.Text = RowVenta("SerieFolio").ToString() + LtlSaldo.Text = Saldo.FormatoNumero + LtlMoneda.Text = RowVenta("Moneda").ToString() + + Dim CondicionesPagoContado As Boolean = RowVenta("CondicionesPago").ToString() = "0" + Dim CveMoneda As Integer = RowVenta("CveMoneda").ToString().ToEntero() + + HdnMoneda.Value = CveMoneda.ToString() + If CveMoneda = 2 Then + DivUSD.Visible = True + TxtTC.Text = GlobalTipoCambio(Now).ToString() + TxtTotalMXN.Text = (TxtImporteContado.Text.ToDecimal() * TxtTC.Text.ToDecimal()).FormatoNumero() + End If + + HdnVentaCondicionesPago.Value = RowVenta("CondicionesPago").ToString() + HdnPlazoCobranza.Value = GvRow.DataKey("PlazoCobranza") + + If UsuarioActual.CveEmpresa.Contiene(189, 193, 195, 196, 197) AndAlso RowVenta("TipoDocto").ToString().Contiene("Rem", "Ant") Then + DivAnticipo.Visible = True + ImgAntiPend.Visible = True + End If + + If CondicionesPagoContado Then + 'según la forma de pago va a establecer el valor para pago. + Select Case CveFormaPago33 + Case "1" + TxtImporteEfectivo.Text = Saldo.FormatoNumero + Case "2" + TxtImporteCheque.Text = Saldo.FormatoNumero + Case "3" + TxtImporteTransferencia.Text = Saldo.FormatoNumero + Case "4" + TxtImporteCredito.Text = Saldo.FormatoNumero + Case "18" + TxtImporteDebito.Text = Saldo.FormatoNumero + Case Else + TxtImporteEfectivo.Text = Saldo.FormatoNumero + End Select + DivContadoBancos.Visible = True + BtnPagar.Text = "Pagar" + Else + DivContadoBancos.Visible = False + BtnPagar.Text = "Emitir a crédito" + End If + + Catch ex As Exception TieneError = True - End If - HdnCveVenta.Value = CveVenta.ToString - HdnCveCliente.Value = GvRow.DataKey("CveCliente") - TxtImporteContado.Text = GvRow.DataKey("Saldo").FormatoNumero - HdnTotal.Value = GvRow.DataKey("Saldo") - TxtImporteEfectivo.Focus() - LtlNombre.Text = GvRow.DataKey("AtencionA") - LtlFolio.Text = GvRow.DataKey("SerieFolio") - LtlSaldo.Text = GvRow.DataKey("Saldo").ToDecimal.FormatoNumero - LtlMoneda.Text = GvRow.DataKey("Moneda") + End Try - Dim CveMoneda As Integer = GvRow.DataKey("CveMoneda").ToEntero() + 'carga información para cobranza - HdnMoneda.Value = CveMoneda.ToString() - If CveMoneda = 2 Then - DivUSD.Visible = True - TxtTC.Text = GlobalTipoCambio(Now).ToString() - TxtTotalMXN.Text = (TxtImporteContado.Text.ToDecimal() * TxtTC.Text.ToDecimal()).FormatoNumero() - End If - - HdnVentaCondicionesPago.Value = GvRow.DataKey("CondicionesPago") - HdnPlazoCobranza.Value = GvRow.DataKey("PlazoCobranza") - - If UsuarioActual.CveEmpresa.Contiene(189, 193, 195, 196, 197) AndAlso GvRow.DataKey("TipoDocto").Contiene("Rem", "Ant") Then - DivAnticipo.Visible = True - ImgAntiPend.Visible = True - End If - - If CondicionesPagoContado Then - 'según la forma de pago va a establecer el valor para pago. - Select Case GvRow.DataKey("CveFormaPago33") - Case "1" - TxtImporteEfectivo.Text = GvRow.DataKey("Saldo").FormatoNumero - Case "2" - TxtImporteCheque.Text = GvRow.DataKey("Saldo").FormatoNumero - Case "3" - TxtImporteTransferencia.Text = GvRow.DataKey("Saldo").FormatoNumero - Case "4" - TxtImporteCredito.Text = GvRow.DataKey("Saldo").FormatoNumero - Case "18" - TxtImporteDebito.Text = GvRow.DataKey("Saldo").FormatoNumero - Case Else - TxtImporteEfectivo.Text = GvRow.DataKey("Saldo").FormatoNumero - End Select - DivContadoBancos.Visible = True - BtnPagar.Text = "Pagar" + If Not TieneError Then + ObjVentas.Commit() + PnlContado.Visible = True Else - DivContadoBancos.Visible = False - BtnPagar.Text = "Emitir a crédito" + ObjVentas.RollBack() + PnlContado.Visible = False + Alert("Hubo un error al asignar datos de cobranza", TipoMensaje.MsgInformacion) End If - Catch ex As Exception - TieneError = True - End Try - - 'carga información para cobranza - - If Not TieneError Then - ObjVentas.Commit() - PnlContado.Visible = True - Else - ObjVentas.RollBack() - PnlContado.Visible = False - Alert("Hubo un error al asignar datos de cobranza", TipoMensaje.MsgInformacion) - End If - - ObjVentas.Dispose() - 'CargaDatos() + ObjVentas.Dispose() + End If + + + 'CargaDatos() End If End Sub diff --git a/Ventas/Ventas.aspx.vb b/Ventas/Ventas.aspx.vb index 7686c59d3..3e4e4a678 100644 --- a/Ventas/Ventas.aspx.vb +++ b/Ventas/Ventas.aspx.vb @@ -24757,6 +24757,19 @@ Partial Class Ventas Exit Sub End If + 'si es de FNC contado. bloquear edición si está pagada o en proceso de cobro + If UsuarioActual.Empresa.Funcionalidad(109) = "1" Then + Using ObjVta As New ClsVentas + If ObjVta.GetVenta(Me.CveVenta, UsuarioActual.CveEmpresa) Then + Dim DbRowVenta As DataRow = ObjVta.DtResultados.FiltroPrimero("") + If DbRowVenta IsNot Nothing AndAlso (DbRowVenta("CveCobranzaEstatus").ToString = "1" OrElse DbRowVenta("Saldo").ToString.ToDecimal = 0) Then + Alert("No se puede actualizar la información de la remisión porque esta en proceso de cobro. Para aplicar cambios se debera de liberar desde el módulo de 'cobro por caja'.", TipoMensaje.MsgAdvertencia) + Exit Sub + End If + End If + End Using + End If + Dim OcurrioError As Boolean = False Dim ObjVentas As New ClsVentas ObjVentas.IniciaTransacSQL() From d645628e82c2e67504a63d1e7dc4965c37af2fe1 Mon Sep 17 00:00:00 2001 From: JPerez Date: Tue, 10 Jun 2025 20:40:41 -0700 Subject: [PATCH 09/11] --Cambios RepIVA --- Contabilidad/RepIVA.aspx | 16 +- Contabilidad/RepIVA.aspx.cs | 554 ++++++++++++++++++++++++------------ 2 files changed, 384 insertions(+), 186 deletions(-) diff --git a/Contabilidad/RepIVA.aspx b/Contabilidad/RepIVA.aspx index 1ce1ea9f3..e07baa0a6 100644 --- a/Contabilidad/RepIVA.aspx +++ b/Contabilidad/RepIVA.aspx @@ -231,6 +231,14 @@ + + + SubTotal
Imp. No Tan.16%
+
+ + + +
<%-- --%> @@ -318,14 +326,6 @@ - - - SubTotal
Imp. No Tan.16%
-
- - - -
diff --git a/Contabilidad/RepIVA.aspx.cs b/Contabilidad/RepIVA.aspx.cs index 03e1e139b..679812716 100644 --- a/Contabilidad/RepIVA.aspx.cs +++ b/Contabilidad/RepIVA.aspx.cs @@ -7,8 +7,16 @@ using System.Linq; using System.Text; using System.Web.UI; using System.Web.UI.WebControls; -using static Extensiones.ModExtensiones; +using Microsoft.VisualBasic.CompilerServices; +using System.IO; +using GemBox.Spreadsheet; +using System.Globalization; +using System.Text.RegularExpressions; +using System.Drawing; +using static Extensiones.ModExtensiones; +using ADSNetLibrary.SIGAPI.Models.Agropecuaria.Embarques; +//using DocumentFormat.OpenXml.Spreadsheet; public partial class Contabilidad_RepIVA : ClsPaginas { #region PROPIEDADES @@ -30,9 +38,21 @@ public partial class Contabilidad_RepIVA : ClsPaginas } private DataTable DtIVAA { - get { return DtIVAAcreditable = (DataTable)ViewState["DtIVAA"]; } + get { return DtIVAA = (DataTable)ViewState["DtIVAA"]; } set { ViewState["DtIVAA"] = value; } } + private DataTable DtIVA2 + { + get { return DtIVA2 = (DataTable)ViewState["DtIVA2"]; } + set { ViewState["DtIVA2"] = value; } + } + + private DataTable DtRetIVA + { + get { return DtRetIVA = (DataTable)ViewState["DtRetIVA"]; } + set { ViewState["DtRetIVA"] = value; } + } + private double TCEspecifico { get { return TCEspecifico = (double)ViewState["TCEspecifico"]; } @@ -120,7 +140,8 @@ public partial class Contabilidad_RepIVA : ClsPaginas if (ObjCont.GetRepIVAAcumulado(txtFechaI.Text.ToDate(), txtFechaF.Text.ToDate(), Conciliado, 3, DdlCuenta.SelectedValue.ToEntero(), UsuarioActual.CveUsuario, UsuarioActual.CveEmpresa)) { - GvIVA2.DataSource = ObjCont.DtResultados; + DtIVA2 = ObjCont.DtResultados.Copy(); + GvIVA2.DataSource = DtIVA2; } if (UsuarioActual.CveEmpresa == 119) @@ -128,7 +149,8 @@ public partial class Contabilidad_RepIVA : ClsPaginas divRetIVA.Visible = true; if (ObjCont.GetRepIVAAcumulado(txtFechaI.Text.ToDate(), txtFechaF.Text.ToDate(), Conciliado, 4, DdlCuenta.SelectedValue.ToEntero(), UsuarioActual.CveUsuario, UsuarioActual.CveEmpresa)) { - GvRetIVA.DataSource = ObjCont.DtResultados; + DtRetIVA = ObjCont.DtResultados.Copy(); + GvRetIVA.DataSource = DtRetIVA; } } } @@ -192,19 +214,21 @@ public partial class Contabilidad_RepIVA : ClsPaginas protected void LnkPdf_Click(object sender, EventArgs e) { - ImprimirCrystal("PDF"); + //ImprimirCrystal("PDF"); + ImprimirStimulsoft(); + //ImprimirGembox("PDF"); } protected void LnkExcel_Click(object sender, EventArgs e) { - ImprimirGembox(); + ImprimirGembox("EXCEL"); } protected void LnkExcel2_Click(object sender, EventArgs e) { ImprimirCrystal("EXCEL2"); } - private void ImprimirGembox() + private void ImprimirGembox(string Formato) { String FechaF; if (txtFechaF.Text == "" || txtFechaF.Text == "__/__/____") { FechaF = "-1"; } else { FechaF = $"Fecha Final: {txtFechaF.Text}"; } @@ -215,21 +239,323 @@ public partial class Contabilidad_RepIVA : ClsPaginas var filtros = $"Filtros: {FechaI} {FechaF} {TipoMov}"; - GvA.ExportToExcelGembox("ReporteIVA", UsuarioActual, "Reporte de IVA", DatosFiltros: filtros); + var Gv = TT.ActiveTabIndex == 0 ? GvT : GvA; + + var GvExtra1 = TT.ActiveTabIndex == 0 ? GvIEPSA : GvIVA2; + var GvExtra2 = TT.ActiveTabIndex == 0 ? GvIVAA : UsuarioActual.CveEmpresa == 119 ? GvRetIVA : null; + + var NombreHoja = TT.ActiveTabIndex == 0 ? "IVA Trasladado" : "IVA Acreditable"; + + var NombreHojaExtra1 = TT.ActiveTabIndex == 0 ? "IEPS por Porcentaje" : "IVA por Porcentaje"; + var NombreHojaExtra2 = TT.ActiveTabIndex == 0 ? "IVA por Porcentaje" : "Ret IVA"; + + ExportarGembox(Formato, Gv, "ReporteIVA", UsuarioActual, "Reporte de IVA", NombreHoja: NombreHoja, DatosFiltros: filtros, GvExtra1: GvExtra1, NombreHojaExtra1: NombreHojaExtra1, GvExtra2: GvExtra2, NombreHojaExtra2: NombreHojaExtra2); } public override void VerifyRenderingInServerForm(Control control) { } + public void ExportarGembox(String Formato,GridView GridView, string NombreArchivoXLSx, Usuario Usuario, string Titulo, string NombreHoja = "Hoja1", string DatoTituloExtra = "", string DatosFiltros = "", int AnchoImagen = 100, int AlturaImagen = 100, GridView GvExtra1 = null, string NombreHojaExtra1 = "Hoja2", GridView GvExtra2 = null, string NombreHojaExtra2 = "Hoja3") + { + StringWriter stringWriter = new StringWriter(); + HtmlTextWriter writer = new HtmlTextWriter(stringWriter); + GridView.RenderControl(writer); + HtmlLoadOptions htmlDefault = GemBox.Spreadsheet.LoadOptions.HtmlDefault; + MemoryStream memoryStream = new MemoryStream(htmlDefault.Encoding.GetBytes(stringWriter.ToString())); + memoryStream.Position = 0L; + StreamReader streamReader = new StreamReader(memoryStream); + string text = streamReader.ReadToEnd(); + streamReader.Dispose(); + memoryStream.Dispose(); + stringWriter.Dispose(); + string input = text; + input = Regex.Replace(input, "\\<[\\/]*a[^\\>]*\\>", ""); + MemoryStream stream = new MemoryStream(htmlDefault.Encoding.GetBytes(input)); + SpreadsheetInfo.SetLicense(SerialGemBoxSpreadsheet()); + ExcelFile excelFile = ExcelFile.Load(stream, htmlDefault); + checked + { + if (Usuario != null) + { + int num = 6; + int num2 = 2; + ExcelWorksheet excelWorksheet = excelFile.Worksheets[0]; + excelWorksheet.Rows.InsertEmpty(0, num); + foreach (ExcelRow row in excelWorksheet.Rows) + { + foreach (ExcelCell allocatedCell in row.AllocatedCells) + { + if (allocatedCell.Value != null) + { + string s = allocatedCell.Value.ToString().Trim(); + if (decimal.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out var result)) + { + allocatedCell.Value = result; + } + } + } + } + + CellRange usedCellRange = excelWorksheet.GetUsedCellRange(ignoreCellsWithoutValue: true); + if ((object)usedCellRange == null) + { + return; + } + + usedCellRange.Style.Font.Name = "Calibri Light"; + CellRange subrangeAbsolute = excelWorksheet.Cells.GetSubrangeAbsolute(1, usedCellRange.FirstColumnIndex, 1, usedCellRange.LastColumnIndex); + subrangeAbsolute.Merged = true; + subrangeAbsolute.Value = Usuario.Empresa.Empresa; + subrangeAbsolute.Style.Font.Size = 360; + subrangeAbsolute.Style.Font.Name = "Calibri Light"; + subrangeAbsolute.Style.HorizontalAlignment = HorizontalAlignmentStyle.Center; + subrangeAbsolute.Style.VerticalAlignment = VerticalAlignmentStyle.Center; + CellRange subrangeAbsolute2 = excelWorksheet.Cells.GetSubrangeAbsolute(3, usedCellRange.FirstColumnIndex, 3, usedCellRange.LastColumnIndex); + subrangeAbsolute2.Merged = true; + subrangeAbsolute2.Value = Titulo; + subrangeAbsolute2.Style.Font.Size = 400; + subrangeAbsolute2.Style.Font.Name = "Calibri Light"; + subrangeAbsolute2.Style.HorizontalAlignment = HorizontalAlignmentStyle.Center; + subrangeAbsolute2.Style.VerticalAlignment = VerticalAlignmentStyle.Center; + if (DatoTituloExtra.Length > 0) + { + CellRange subrangeAbsolute3 = excelWorksheet.Cells.GetSubrangeAbsolute(num, usedCellRange.FirstColumnIndex, num, usedCellRange.LastColumnIndex); + subrangeAbsolute3.Merged = true; + subrangeAbsolute3.Value = DatoTituloExtra; + subrangeAbsolute3.Style.Font.Size = 400; + subrangeAbsolute3.Style.Font.Name = "Calibri Light"; + subrangeAbsolute3.Style.HorizontalAlignment = HorizontalAlignmentStyle.Left; + subrangeAbsolute3.Style.VerticalAlignment = VerticalAlignmentStyle.Center; + } + + if (DatosFiltros.Length > 0) + { + string[] array = DatosFiltros.Split('|'); + excelWorksheet.Rows.InsertEmpty(num, array.Count()); + string[] array2 = array; + foreach (string value in array2) + { + CellRange subrangeAbsolute4 = excelWorksheet.Cells.GetSubrangeAbsolute(num, usedCellRange.FirstColumnIndex, num, usedCellRange.LastColumnIndex); + subrangeAbsolute4.Merged = true; + subrangeAbsolute4.Value = value; + subrangeAbsolute4.Style.Font.Size = 240; + subrangeAbsolute4.Style.Font.Name = "Calibri Light"; + subrangeAbsolute4.Style.HorizontalAlignment = HorizontalAlignmentStyle.Left; + subrangeAbsolute4.Style.VerticalAlignment = VerticalAlignmentStyle.Center; + num++; + } + } + + int firstColumnIndex = usedCellRange.FirstColumnIndex; + int lastColumnIndex = usedCellRange.LastColumnIndex; + for (int j = firstColumnIndex; j <= lastColumnIndex; j++) + { + excelWorksheet.Rows[num].Cells[j].Style.Font.Size = 240; + excelWorksheet.Rows[num].Cells[j].Style.HorizontalAlignment = HorizontalAlignmentStyle.Center; + excelWorksheet.Rows[num].Cells[j].Style.VerticalAlignment = VerticalAlignmentStyle.Center; + excelWorksheet.Rows[num].Cells[j].Style.FillPattern.SetPattern(FillPatternStyle.Solid, SpreadsheetColor.FromArgb(75, 119, 190), SpreadsheetColor.FromArgb(255, 255, 255)); + excelWorksheet.Rows[num].Cells[j].Style.Font.Color = SpreadsheetColor.FromArgb(255, 255, 255); + if (j > 0) + { + try + { + excelWorksheet.Columns[j].AutoFit(1.0); + } + catch (Exception ex) + { + ProjectData.SetProjectError(ex); + Exception ex2 = ex; + ProjectData.ClearProjectError(); + } + } + } + + int num3 = GridView.Rows.Count + num + num2; + excelWorksheet.Rows[num3].Cells[1].Value = "Usuario Imprimió"; + excelWorksheet.Rows[num3 + 1].Cells[1].Value = Usuario.Nombre; + excelWorksheet.Rows[num3].Cells[3].Value = "Fecha Impresión"; + excelWorksheet.Rows[num3 + 1].Cells[3].Value = ClsPaginas.NowADS().ToString("dd/MM/yyyy"); + FileInfo fileInfo = new FileInfo($"{Usuario.Empresa.Ruta}/Logo.png"); + if (fileInfo.Exists) + { + string path = $"{Usuario.Empresa.Ruta}/Logo.png"; + using StreamReader streamReader2 = new StreamReader(path); + MemoryStream memoryStream2 = new MemoryStream(); + streamReader2.BaseStream.CopyTo(memoryStream2); + excelWorksheet.Pictures.Add(memoryStream2, ExcelPictureFormat.Png, "A1", AnchoImagen, AlturaImagen, LengthUnit.Pixel); + } + + int firstColumnIndex2 = usedCellRange.FirstColumnIndex; + int lastColumnIndex2 = usedCellRange.LastColumnIndex; + for (int k = firstColumnIndex2; k <= lastColumnIndex2; k++) + { + if (k > 0) + { + bool flag = true; + excelWorksheet.Columns[k + 1].Style.NumberFormat = "#,##0.00"; + try + { + excelWorksheet.Columns[k].AutoFit(1.0); + } + catch (Exception ex3) + { + ProjectData.SetProjectError(ex3); + Exception ex4 = ex3; + ProjectData.ClearProjectError(); + } + } + } + + excelFile.Worksheets[0].Name = NombreHoja; + + if (GvExtra1 != null) + { + StringWriter stringWriter1 = new StringWriter(); + HtmlTextWriter writer1 = new HtmlTextWriter(stringWriter1); + GvExtra1.RenderControl(writer1); + + MemoryStream memoryStream1 = new MemoryStream(htmlDefault.Encoding.GetBytes(stringWriter1.ToString())); + memoryStream1.Position = 0L; + StreamReader streamReader1 = new StreamReader(memoryStream1); + string input1 = streamReader1.ReadToEnd(); + + streamReader1.Dispose(); + memoryStream1.Dispose(); + stringWriter1.Dispose(); + + input1 = Regex.Replace(input1, "\\<[\\/]*a[^\\>]*\\>", ""); + MemoryStream stream1 = new MemoryStream(htmlDefault.Encoding.GetBytes(input1)); + SpreadsheetInfo.SetLicense(SerialGemBoxSpreadsheet()); + + ExcelFile excelFile2 = ExcelFile.Load(stream1, htmlDefault); + + ExcelWorksheet excelWorksheet2 = excelFile2.Worksheets[0]; + int num4 = excelWorksheet2.CalculateMaxUsedColumns(); + int num5 = num4 - 1; + for (int l = 0; l <= num5; l++) + { + excelWorksheet2.Columns[l].AutoFit(1.0, excelWorksheet2.Rows[1], excelWorksheet2.Rows[excelWorksheet2.Rows.Count - 1]); + + excelWorksheet2.Cells[0, l].Style.FillPattern.SetSolid(ColorTranslator.FromHtml("#4b77be")); + excelWorksheet2.Cells[0, l].Style.Font.Color = SpreadsheetColor.FromArgb(255, 255, 255); + } + + excelFile.Worksheets.AddCopy(NombreHojaExtra1, excelWorksheet2); + } + + if (GvExtra2 != null) + { + StringWriter stringWriter2 = new StringWriter(); + HtmlTextWriter writer2 = new HtmlTextWriter(stringWriter2); + GvExtra2.RenderControl(writer2); + + MemoryStream memoryStream2 = new MemoryStream(htmlDefault.Encoding.GetBytes(stringWriter2.ToString())); + memoryStream2.Position = 0L; + StreamReader streamReader2 = new StreamReader(memoryStream2); + string input2 = streamReader2.ReadToEnd(); + + streamReader2.Dispose(); + memoryStream2.Dispose(); + stringWriter2.Dispose(); + + input2 = Regex.Replace(input2, "\\<[\\/]*a[^\\>]*\\>", ""); + MemoryStream stream2 = new MemoryStream(htmlDefault.Encoding.GetBytes(input2)); + SpreadsheetInfo.SetLicense(SerialGemBoxSpreadsheet()); + + ExcelFile excelFile3 = ExcelFile.Load(stream2, htmlDefault); + + ExcelWorksheet excelWorksheet3 = excelFile3.Worksheets[0]; + int num4 = excelWorksheet3.CalculateMaxUsedColumns(); + int num5 = num4 - 1; + + for (int l = 0; l <= num5; l++) + { + excelWorksheet3.Columns[l].AutoFit(1.0, excelWorksheet3.Rows[1], excelWorksheet3.Rows[excelWorksheet3.Rows.Count - 1]); + excelWorksheet3.Cells[0, l].Style.FillPattern.SetSolid(ColorTranslator.FromHtml("#4b77be")); + excelWorksheet3.Cells[0, l].Style.Font.Color = SpreadsheetColor.FromArgb(255, 255, 255); + } + + excelFile.Worksheets.AddCopy(NombreHojaExtra2, excelWorksheet3); + } + + int num6 = 8; + int num7 = 0; + int num8 = -1; + if (DatosFiltros.Trim().Length > 0) + { + num8 = 0; + } + + int num9 = excelWorksheet.Rows.Count - 4; + for (num6 = 8; num6 <= num9; num6++) + { + try + { + switch (GridView.Rows[num7].CssClass.Trim()) + { + case "Totales": + excelWorksheet.Cells.GetSubrangeRelative(num6 + num8, 0, usedCellRange.LastColumnIndex + 1, 1).Style.FillPattern.SetSolid(ColorTranslator.FromHtml("#67809f")); + excelWorksheet.Cells.GetSubrangeRelative(num6 + num8, 0, usedCellRange.LastColumnIndex + 1, 1).Style.Font.Weight = 1000; + excelWorksheet.Cells.GetSubrangeRelative(num6 + num8, 0, usedCellRange.LastColumnIndex + 1, 1).Style.Font.Color = ColorTranslator.FromHtml("#ddd"); + break; + case "SubTotales2": + excelWorksheet.Cells.GetSubrangeRelative(num6 + num8, 0, usedCellRange.LastColumnIndex + 1, 1).Style.FillPattern.SetSolid(ColorTranslator.FromHtml("#c0c0c0")); + excelWorksheet.Cells.GetSubrangeRelative(num6 + num8, 0, usedCellRange.LastColumnIndex + 1, 1).Style.Font.Weight = 1000; + excelWorksheet.Cells.GetSubrangeRelative(num6 + num8, 0, usedCellRange.LastColumnIndex + 1, 1).Style.Font.Color = ColorTranslator.FromHtml("#000077"); + break; + case "SubTotales": + excelWorksheet.Cells.GetSubrangeRelative(num6 + num8, 0, usedCellRange.LastColumnIndex + 1, 1).Style.FillPattern.SetSolid(ColorTranslator.FromHtml("#dddddd")); + excelWorksheet.Cells.GetSubrangeRelative(num6 + num8, 0, usedCellRange.LastColumnIndex + 1, 1).Style.Font.Weight = 1000; + excelWorksheet.Cells.GetSubrangeRelative(num6 + num8, 0, usedCellRange.LastColumnIndex + 1, 1).Style.Font.Color = ColorTranslator.FromHtml("#67809F"); + break; + } + } + catch (Exception ex5) + { + ProjectData.SetProjectError(ex5); + Exception ex6 = ex5; + ProjectData.ClearProjectError(); + } + + num7++; + } + } + + if (Formato == "EXCEL") + { + excelFile.Save(System.Web.HttpContext.Current.Response, $"{NombreArchivoXLSx}.xlsx"); + } + else + { + foreach (var worksheet in excelFile.Worksheets) + { + var printOptions = worksheet.PrintOptions; + printOptions.LeftMargin = + printOptions.RightMargin = + printOptions.TopMargin = + printOptions.BottomMargin = 0; + + printOptions.AutomaticPageBreakScalingFactor = 93; + printOptions.Portrait = false; + } + + var saveOptions = new PdfSaveOptions(); + saveOptions.SelectionType = SelectionType.EntireFile; + + excelFile.Save(System.Web.HttpContext.Current.Response, $"{NombreArchivoXLSx}.pdf", saveOptions); + } + } + } + public void ImprimirStimulsoft() { String FechaF; - if (txtFechaF.Text == "" || txtFechaF.Text == "__/__/____") { FechaF = "-1"; } else { FechaF = $" Fecha Final: {txtFechaF.Text}"; } + if (txtFechaF.Text == "" || txtFechaF.Text == "__/__/____") { FechaF = "-1"; } else { FechaF = $"Fecha Final:{txtFechaF.Text}"; } String FechaI; - if (txtFechaI.Text == "" || txtFechaI.Text == "__/__/____") { FechaI = "-1"; } else { FechaI = $" Fecha Inicial: {txtFechaI.Text}"; } + if (txtFechaI.Text == "" || txtFechaI.Text == "__/__/____") { FechaI = "-1"; } else { FechaI = $"Fecha Inicial: {txtFechaI.Text} "; } String TipoMov; - if (DdlTipoMovto.SelectedItem.Text == "Todos") { TipoMov = ""; } else { TipoMov = $" Tipo Movimiento: {DdlTipoMovto.SelectedItem.Text}"; } + if (DdlTipoMovto.SelectedItem.Text == "Todos") { TipoMov = ""; } else { TipoMov = $"Tipo Movimiento: {DdlTipoMovto.SelectedItem.Text} "; } if (GvT.Rows.Count > 0 || GvA.Rows.Count > 0) { @@ -247,7 +573,7 @@ public partial class Contabilidad_RepIVA : ClsPaginas List para = new List(); para.Add(new ReportParameter("Empresa", UsuarioActual.Empresa.Empresa)); para.Add(new ReportParameter("UsuarioImprimio", UsuarioActual.Nombre)); - para.Add(new ReportParameter("Filtros", $"Filtros: {FechaI}{FechaF}{TipoMov}")); + para.Add(new ReportParameter("Filtros", $"Filtros: {FechaI}{FechaF}{TipoMov}")); if (Imagen.Exists) { @@ -258,8 +584,9 @@ public partial class Contabilidad_RepIVA : ClsPaginas para.Add(new ReportParameter("LogoPath", "")); } - DataTable Dt = DtIVAAcreditable.Copy(); - string Formato = "RepIVAAcreditable.mrt"; + DataTable Dt = TT.ActiveTabIndex == 0 ? DtIVATrasladado.Copy() : DtIVAAcreditable.Copy(); + + string Formato = TT.ActiveTabIndex == 0 ? "RepIVA.mrt" : "RepIVAAcreditable.mrt"; para.Add(new ReportParameter("Formato", "PDF")); @@ -270,24 +597,48 @@ public partial class Contabilidad_RepIVA : ClsPaginas List lrds = new List(); ReportDataSource rds = new ReportDataSource(); - rds.Name = "RepIVAAcreditable"; + rds.Name = TT.ActiveTabIndex == 0 ? "RepIVA" : "RepIVAAcreditable"; rds.Value = Dt; lrds.Add(rds); - if (DtIEPSA != null) + //RepIVA + if (TT.ActiveTabIndex == 0) { - ReportDataSource rds2 = new ReportDataSource(); - rds2.Name = "IEPSPorcentaje"; - rds2.Value = DtIEPSA; - lrds.Add(rds2); + if (DtIEPSA != null) + { + ReportDataSource rds2 = new ReportDataSource(); + rds2.Name = "IEPSPorcentaje"; + rds2.Value = DtIEPSA; + lrds.Add(rds2); + } + + if (DtIVAA != null) + { + ReportDataSource rds3 = new ReportDataSource(); + rds3.Name = "IVAPorcentaje"; + rds3.Value = DtIVAA; + lrds.Add(rds3); + } } - if (DtIVAA != null) + //RepIVAAcreditable + if (TT.ActiveTabIndex == 1) { - ReportDataSource rds3 = new ReportDataSource(); - rds3.Name = "IVAPorcentaje"; - rds3.Value = DtIVAA; - lrds.Add(rds3); + if (DtIVA2 != null) + { + ReportDataSource rds4 = new ReportDataSource(); + rds4.Name = "IVAPorcentaje"; + rds4.Value = DtIVA2; + lrds.Add(rds4); + } + + if (DtRetIVA != null) + { + ReportDataSource rds5 = new ReportDataSource(); + rds5.Name = "RetIVAPorcentaje"; + rds5.Value = DtRetIVA; + lrds.Add(rds5); + } } string Extension = "pdf"; @@ -424,7 +775,6 @@ public partial class Contabilidad_RepIVA : ClsPaginas protected void LnkTxtDIOT_Click(object sender, EventArgs e) { - StringBuilder SBDIOT = new StringBuilder(); int Conciliado = DdlTipoMovto.SelectedValue.ToEntero(); @@ -568,28 +918,6 @@ public partial class Contabilidad_RepIVA : ClsPaginas } } - - - - - //MemoryStream ms = new MemoryStream(); - //TextWriter tw = new StreamWriter(ms, System.Text.Encoding.UTF8); - - //tw.Write(SBDIOT.ToString()); - - //tw.Flush(); - - //byte[] bytes = ms.ToArray(); - //ms.Close(); - - //Response.Clear(); - //Response.AppendHeader("Content-Length", text.Length.ToString()); - //Response.ContentType = "text/plain"; - //Response.AddHeader("content-disposition", $"attachment; filename=DIOT_{ txtFechaI.Text.ToDate().ToString("ddMMyyyy") }_{txtFechaI.Text.ToDate().ToString("ddMMyyyy") }.txt"); - //Response.BinaryWrite(bytes); - //Response.End(); - - } static DataTable AcumularYReemplazar(DataTable dt) @@ -704,136 +1032,6 @@ public partial class Contabilidad_RepIVA : ClsPaginas } } - //public void IImprimirbytesPDF(byte[] bytes, string NombreArchivo = "Reporte", string Formato = "PDF", bool Descarga = false, string Content_Disposition = "attachment", string Extension = "") - //{ - // // limpio ReportViwer - // string mimeType = null; - // // If Descarga Then - // // Try - // // bytes = bytes - // // File.WriteAllBytes(String.Format("{0}PDF/whatever.gif", UsuarioActual.Empresa.Ruta), img) - // // Catch ex As Exception - // // If UsuarioActual.CveRol = 1 Then - // // Alert(ex.Message, TipoMensaje.MsgAdvertencia) - // // Else - // // Alert("Ocurrió un error al generar la descarga. Favor de contactar a soporte tecnico cod'IMPDFclspag'", TipoMensaje.MsgAdvertencia) - // // End If - // // End Try - // // End If - // try - // { - // bytes = bytes; - // //Response.Buffer = true; - // //Response.Clear(); - // //if (Formato == "PDF") - // // Response.ContentType = "application/pdf"; - // //else - // // Response.ContentType = mimeType; - // //Response.ClearHeaders(); - // //string fileExtension = ""; - // //if (!string.IsNullOrEmpty(Extension)) - // // fileExtension = Extension; - // //else - // // fileExtension = Formato == "PDF" ? "pdf" : "xls"; - // //Response.AddHeader("content-disposition", string.Format("{0}; filename=\"{1}.{2}\"", Content_Disposition, NombreArchivo, fileExtension)); - // //Response.BinaryWrite(bytes); // create the file - // //Response.Flush(); // send it to the client to download - // //bytes = null; - // //HttpContext.Current.Response.SuppressContent = true; - // //HttpContext.Current.ApplicationInstance.CompleteRequest(); - // Alert("ok"); - // } - // // HttpContext.Current.Response.End() - // catch (Exception ex) - // { - // if (UsuarioActual.CveRol == 1) { - - // } - // else - // Alert("Ocurrió un error al generar la descarga. Favor de contactar a soporte tecnico cod:'IMPDFclspag'", TipoMensaje.MsgAdvertencia); - // } - //} - - - //public byte[] IImprimirSubRepPDFCrystal(string RutaReporte, DataTable DataSource, List Parametros, DataTable DataSource1, DataTable DataSource2, string SubRep1, string SubRep2, string NombreArchivo = "Reporte", string Formato = "PDF", ReportDocument MR = null/* TODO Change to default(_) if this is not a reference type */) - //{ - // // limpio ReportViwer - // Stopwatch sw = Stopwatch.StartNew(); - - // if (MR == null) - // MR = new ReportDocument(); - // ReportDocument SR1 = new ReportDocument(); - // ReportDocument SR2 = new ReportDocument(); - // byte[] Bytes = null; - // ExportFormatType formatType = ExportFormatType.NoFormat; - // try - // { - // MR.Load(RutaReporte); - // SR1 = MR.OpenSubreport(SubRep1); - // SR2 = MR.OpenSubreport(SubRep2); - // MR.SetDataSource(DataSource); - // SR1.SetDataSource(DataSource1); - // SR2.SetDataSource(DataSource2); - // foreach (CrystalParametro item in Parametros) - // MR.SetParameterValue(item.Nombre, item.Valor); - // switch (Formato) - // { - // case "PDF": - // { - // formatType = ExportFormatType.PortableDocFormat; - // break; - // } - - // case "EXCEL": - // { - // formatType = ExportFormatType.Excel; - // break; - // } - // } - // System.IO.Stream Stream = MR.ExportToStream(formatType); - // BinaryReader BD = new BinaryReader(MR.ExportToStream(formatType)); - // Bytes = BD.ReadBytes(System.Convert.ToInt32(MR.ExportToStream(formatType).Length)); - // BD.Dispose(); - // Stream.Dispose(); - // } - // // Dim Buffer(CInt(Stream.Length)) As Byte - // // Bytes = Buffer - // // MR.ExportToHttpResponse(formatType, Response, True, NombreArchivo) - // catch (CrystalReportsException ex) - // { - // if(ex.Message != null) - // { - // Alert(ex.Message); - // } - // if (ex.InnerException != null) - // { - // Alert(ex.InnerException.Message); - // } - - // } - // // HAY QUE VALIDAR QUE LOS OBJETOS QUE SE USAN PARA GUARDAR LOG EXISTEN!!! IPP 14 AGOSTO 2017 - // // GuardaLog($"Error: {ex.InnerException.Message} | Descripcion: {If(ex.InnerException.InnerException IsNot Nothing, ex.InnerException.InnerException.Message, "Sin descripcion")} - Ruta {RutaReporte}") - // catch (Exception ex) - // { - // //GuardaLog(ex.InnerException != null && ex.Message != null ? $"Error: {ex.InnerException.Message ?? ex.Message} | Descripcion: {ex.InnerException != null && ex.InnerException.InnerException != null && ex.InnerException.InnerException.Message != null ? ex.InnerException.InnerException.Message : ex.InnerException != null && ex.InnerException.Message != null ? ex.InnerException.Message : "Sin descripcion"} Ruta {RutaReporte}" : $"Sin descripción - Ruta {RutaReporte}"); - // if (ex.Message != null) - // { - // Alert(ex.Message); - // } - // if (ex.InnerException != null) - // { - // Alert(ex.InnerException.Message); - // } - // } - // sw.Stop(); - // if (sw.Elapsed.TotalSeconds > 10) - // // GuardaLog($"Reporte:{RutaReporte} | Tiempo Renderizado Milisegundos: {sw.ElapsedMilliseconds},Total Segundos: {sw.Elapsed.TotalSeconds} "); - // if (MR != null) - // MR.Dispose(); - // return Bytes; - //} - - protected void GvIEPSA_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow && e.Row.DataKey("PorcentajeIEPS").Trim() == "") From 04b977e50ff2f87c9d04070853fff8342c87a2d8 Mon Sep 17 00:00:00 2001 From: JPerez Date: Wed, 11 Jun 2025 11:07:44 -0700 Subject: [PATCH 10/11] =?UTF-8?q?--Correci=C3=B3n=20ortografica?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ventas/Ventas.aspx.vb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ventas/Ventas.aspx.vb b/Ventas/Ventas.aspx.vb index 3e4e4a678..31cc18ddf 100644 --- a/Ventas/Ventas.aspx.vb +++ b/Ventas/Ventas.aspx.vb @@ -33176,7 +33176,7 @@ Partial Class Ventas Next If Not Selecciono Then - Alert("Tiene que seleccionar al menos un concepto y este dege tener una cantidad mayor a 0. Por favor verifique y vuelva a intentar", TipoMensaje.MsgAdvertencia) + Alert("Tiene que seleccionar al menos un concepto y este debe tener una cantidad mayor a 0. Por favor verifique y vuelva a intentar", TipoMensaje.MsgAdvertencia) Exit Sub End If From d121e0de65baac33f2ea33ecbc1c3b074cf60462 Mon Sep 17 00:00:00 2001 From: Luis Carlos Quijada Date: Wed, 11 Jun 2025 17:21:37 -0600 Subject: [PATCH 11/11] Cambios Dashboard Graficas --- App_Code/ClsGenerales.vb | 96 +-- Contabilidad/RepAnexoCatalogoCC.aspx | 2 +- General/Dashboard.aspx | 1109 ++++++++++++++++++++++++-- General/Dashboard.aspx.vb | 417 +++++++++- 4 files changed, 1481 insertions(+), 143 deletions(-) diff --git a/App_Code/ClsGenerales.vb b/App_Code/ClsGenerales.vb index 1e444e23b..37a62c152 100644 --- a/App_Code/ClsGenerales.vb +++ b/App_Code/ClsGenerales.vb @@ -748,55 +748,55 @@ Public Class ClsGenerales End Try Return Retorno - End Function - + End Function + #End Region - - '#Region " E S T A D O S" - ' Public Function GetGralEstados() As Boolean - ' Dim Retorno As Boolean = False - ' DataAdapter("PA_Gral_EstadoGet") - ' Try - ' SqlAdapter.Fill(Data) - ' Retorno = True - ' Catch ex As Exception - ' OnError("Ocurrió un error al obtener el Catálogo de Estados.", ex, SqlAdapter.SelectCommand.Parameters.ParametrosInfo()) - ' End Try - - ' Return Retorno - ' End Function - '#End Region - - '#Region " M U N I C I P I O S" - ' Public Function GetGralMunicipios() As Boolean - ' Dim Retorno As Boolean = False - ' DataAdapter("PA_Gral_MunicipioGet") - ' Try - ' SqlAdapter.Fill(Data) - ' Retorno = True - ' Catch ex As Exception - ' OnError("Ocurrió un error al obtener el Catálogo de Municipios.", ex, SqlAdapter.SelectCommand.Parameters.ParametrosInfo()) - ' End Try - - ' Return Retorno - ' End Function - '#End Region - - '#Region " P A I S E S" - ' Public Function GetGralPaises() As Boolean - ' Dim Retorno As Boolean = False - ' DataAdapter("PA_Gral_PaisGet") - ' Try - ' SqlAdapter.Fill(Data) - ' Retorno = True - ' Catch ex As Exception - ' OnError("Ocurrió un error al obtener el Catálogo de Paises.", ex, SqlAdapter.SelectCommand.Parameters.ParametrosInfo()) - ' End Try - - ' Return Retorno - ' End Function - '#End Region - + + '#Region " E S T A D O S" + ' Public Function GetGralEstados() As Boolean + ' Dim Retorno As Boolean = False + ' DataAdapter("PA_Gral_EstadoGet") + ' Try + ' SqlAdapter.Fill(Data) + ' Retorno = True + ' Catch ex As Exception + ' OnError("Ocurrió un error al obtener el Catálogo de Estados.", ex, SqlAdapter.SelectCommand.Parameters.ParametrosInfo()) + ' End Try + + ' Return Retorno + ' End Function + '#End Region + + '#Region " M U N I C I P I O S" + ' Public Function GetGralMunicipios() As Boolean + ' Dim Retorno As Boolean = False + ' DataAdapter("PA_Gral_MunicipioGet") + ' Try + ' SqlAdapter.Fill(Data) + ' Retorno = True + ' Catch ex As Exception + ' OnError("Ocurrió un error al obtener el Catálogo de Municipios.", ex, SqlAdapter.SelectCommand.Parameters.ParametrosInfo()) + ' End Try + + ' Return Retorno + ' End Function + '#End Region + + '#Region " P A I S E S" + ' Public Function GetGralPaises() As Boolean + ' Dim Retorno As Boolean = False + ' DataAdapter("PA_Gral_PaisGet") + ' Try + ' SqlAdapter.Fill(Data) + ' Retorno = True + ' Catch ex As Exception + ' OnError("Ocurrió un error al obtener el Catálogo de Paises.", ex, SqlAdapter.SelectCommand.Parameters.ParametrosInfo()) + ' End Try + + ' Return Retorno + ' End Function + '#End Region + #Region " P O B L A C I O N E S" Public Function GetGralPoblaciones() As Boolean Dim Retorno As Boolean = False diff --git a/Contabilidad/RepAnexoCatalogoCC.aspx b/Contabilidad/RepAnexoCatalogoCC.aspx index 0e105651a..d05a8aad4 100644 --- a/Contabilidad/RepAnexoCatalogoCC.aspx +++ b/Contabilidad/RepAnexoCatalogoCC.aspx @@ -574,7 +574,7 @@ @@ -1049,6 +1866,166 @@ } + function generarGraficaSucursales() { + // 1) Obtener la tabla completa + var $grid = $('table[id$="gvResumenSucursales"]'); + + // 2) Buscar TODOS los checkbox marcados + var $checks = $grid.find('input.header-checkbox:checked'); + if ($checks.length === 0) { + alert('Por favor, seleccione al menos una columna para graficar.'); + return false; + } + + // 3) Filas de datos: todas las que tengan + var $dataRows = $grid.find('tr').has('td'); + + // 4) Categorías = texto de la primera celda (Sucursal) + var categorias = $dataRows.map(function () { + return $(this).find('td').eq(0).text().trim(); + }).get(); + + // 5) Localizar tus subheaders (segunda fila de encabezado) + var $headerRows = $grid.find('tr').filter(function () { + return $(this).find('th').length > 1; + }); + var $subThs = $headerRows.eq(1).find('th'); // esos 4 + + // 6) Construir las series + var series = $checks.map(function () { + var $chk = $(this); + var $th = $chk.closest('th'); + // idxSub = posición dentro de los 4 subheaders (0..3) + var idxSub = $subThs.index($th); + // +1 porque la columna 0 es "Sucursal" + var colIndex = idxSub + 1; + // Leer data-field (VentaAnual, UtilidadAnual, etc.) y formatear nombre + var field = $chk.data('field'); + var name = field.replace(/([a-z])([A-Z])/g, '$1 $2'); + // Mapear los valores de cada fila para esta columna + var data = $dataRows.map(function () { + var txt = $(this).find('td').eq(colIndex).text().replace(/,/g, ''); + return parseFloat(txt) || 0; + }).get(); + return { name: name, data: data }; + }).get(); + + // 7) Dibujar Highcharts + Highcharts.chart('chartContainer', { + chart: { type: 'line' }, + title: { text: 'Comparativo por Sucursal' }, + xAxis: { + categories: categorias, + title: { text: 'Sucursal' } + }, + yAxis: { + title: { text: 'Monto' }, + labels: { + formatter: function () { + return '$' + Highcharts.numberFormat(this.value, 0); + } + } + }, + tooltip: { + headerFormat: '{series.name}
', + pointFormat: 'Sucursal: {point.category}
Valor: ${point.y:,.2f}' + }, + plotOptions: { + series: { marker: { enabled: true } } + }, + series: series + }); + + // 8) Mostrar el modal + $('#DivModalGrafica').modal('show'); + return false; + } + + function generarGrafica(gridId) { + var $grid = $('#' + gridId); + + // Encuentra las filas de encabezado (donde están los checkboxes) + var $headerRows = $grid.find('tr:has(th)'); + var $subHeader = $headerRows.length > 1 ? $headerRows.eq(1) : $headerRows.eq(0); + var $subThs = $subHeader.find('th'); + + // Buscar checkboxes marcados + var $checks = $grid.find('input.header-checkbox:checked'); + if ($checks.length === 0) { + alert('Por favor, seleccione al menos una columna para graficar.'); + return false; + } + + // Filas de datos + var $dataRows = $grid.find('tr').has('td'); + + // Categorías (eje X) + var categorias = $dataRows.map(function () { + return $(this).find('td').eq(0).text().trim(); + }).get(); + + // Construir series + var series = []; + $checks.each(function () { + var $chk = $(this); + var field = $chk.data('field'); + + // Buscar el índice de la columna que tiene ese data-field + var colIndex = -1; + $subThs.each(function (i) { + var $input = $(this).find('input.header-checkbox'); + if ($input.length && $input.data('field') === field) { + colIndex = i + 1; // +1 porque la primera columna es la de las categorías + } + }); + + if (colIndex === -1) return; // No encontrado, saltar + + var name = field.replace(/([a-z])([A-Z])/g, '$1 $2'); + var data = $dataRows.map(function () { + var txt = $(this).find('td').eq(colIndex).text().replace(/,/g, ''); + return parseFloat(txt) || 0; + }).get(); + + series.push({ name: name, data: data }); + }); + + // Título dinámico + var titulo = $grid.closest('.portlet').find('.caption-subject').text(); + var modalTitulo = document.getElementById('modalTitulo'); + if (modalTitulo) modalTitulo.innerText = 'Comparativo: ' + titulo; + + // Dibujar gráfica + Highcharts.chart('chartContainer', { + chart: { type: 'line' }, + title: { text: titulo }, // Usar el título dinámico + xAxis: { + categories: categorias, + title: { text: 'Categoría' } // Título genérico para el eje X + }, + yAxis: { + title: { text: 'Monto (MXN)' }, + labels: { + formatter: function () { + return '$' + Highcharts.numberFormat(this.value, 0); + } + } + }, + tooltip: { + headerFormat: '{series.name}
', + pointFormat: 'Categoría: {point.category}
Valor: ${point.y:,.2f}' + }, + plotOptions: { + series: { marker: { enabled: true } } + }, + series: series + }); + + $('#DivModalGrafica').modal('show'); + return false; + } + + diff --git a/General/Dashboard.aspx.vb b/General/Dashboard.aspx.vb index b3f4a34bc..5fe165fe6 100644 --- a/General/Dashboard.aspx.vb +++ b/General/Dashboard.aspx.vb @@ -373,50 +373,411 @@ Partial Class General_Dashboard Protected Sub gvResumenSucursales_RowCreated(sender As Object, e As GridViewRowEventArgs) If e.Row.RowType = DataControlRowType.Header Then - ' Limpiar celdas originales e.Row.Cells.Clear() + Dim grid As GridView = DirectCast(sender, GridView) - ' Crear primera fila de encabezado (grupos) - Dim headerRow As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal) + ' --- Fila 1 --- + Dim headerRow1 As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal) - ' Celda para "Sucursal" (ocupa 2 filas) Dim cellSucursal As New TableHeaderCell() cellSucursal.RowSpan = 2 - cellSucursal.Text = "Sucursal" - headerRow.Cells.Add(cellSucursal) + cellSucursal.VerticalAlign = VerticalAlign.Middle + cellSucursal.Controls.Add(New LiteralControl("Sucursal ")) + Dim hypGrafica As New HyperLink() + hypGrafica.NavigateUrl = "javascript:void(0);" + hypGrafica.Attributes.Add("onclick", "return generarGraficaSucursales();") + hypGrafica.CssClass = "grafica-icon" + hypGrafica.Controls.Add(New LiteralControl("")) + cellSucursal.Controls.Add(hypGrafica) + headerRow1.Cells.Add(cellSucursal) - ' Celda para "Año" (abarca 2 columnas) - Dim cellAño As New TableHeaderCell() - cellAño.ColumnSpan = 2 - cellAño.Text = "Año" - headerRow.Cells.Add(cellAño) + Dim cellAnio As New TableHeaderCell() + cellAnio.ColumnSpan = 2 + cellAnio.HorizontalAlign = HorizontalAlign.Center + cellAnio.Text = "Año" + headerRow1.Cells.Add(cellAnio) - ' Celda para "Mes" (abarca 2 columnas) Dim cellMes As New TableHeaderCell() cellMes.ColumnSpan = 2 + cellMes.HorizontalAlign = HorizontalAlign.Center cellMes.Text = "Mes" - headerRow.Cells.Add(cellMes) + headerRow1.Cells.Add(cellMes) - ' Añadir fila al GridView - Dim grid As GridView = DirectCast(sender, GridView) - grid.Controls(0).Controls.AddAt(0, headerRow) + headerRow1.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(0, headerRow1) - ' Crear segunda fila de encabezado (subtítulos) - Dim subHeaderRow As New GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal) - - ' Subtítulos para "Año" - subHeaderRow.Cells.Add(New TableHeaderCell() With {.Text = "Venta"}) - subHeaderRow.Cells.Add(New TableHeaderCell() With {.Text = "Utilidad"}) - - ' Subtítulos para "Mes" - subHeaderRow.Cells.Add(New TableHeaderCell() With {.Text = "Venta"}) - subHeaderRow.Cells.Add(New TableHeaderCell() With {.Text = "Utilidad"}) - - grid.Controls(0).Controls.AddAt(1, subHeaderRow) + ' --- Fila 2 --- + Dim headerRow2 As New GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal) + headerRow2.Cells.Add(CreateSubHeaderCell("Venta", "chkVentaAnual", "VentaAnual")) + headerRow2.Cells.Add(CreateSubHeaderCell("Utilidad", "chkUtilidadAnual", "UtilidadAnual")) + headerRow2.Cells.Add(CreateSubHeaderCell("Venta", "chkVentaMensual", "VentaMensual")) + headerRow2.Cells.Add(CreateSubHeaderCell("Utilidad", "chkUtilidadMensual", "UtilidadMensual")) + headerRow2.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(1, headerRow2) End If End Sub + Protected Sub gvVentasPorSucursal_RowCreated(sender As Object, e As GridViewRowEventArgs) + If e.Row.RowType = DataControlRowType.Header Then + e.Row.Cells.Clear() + Dim grid As GridView = DirectCast(sender, GridView) + + ' --- Fila 1 --- + Dim headerRow1 As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Celda principal (Sucursal) + Dim cellSucursal As New TableHeaderCell() + cellSucursal.RowSpan = 2 + cellSucursal.VerticalAlign = VerticalAlign.Middle + cellSucursal.Controls.Add(New LiteralControl("Sucursal ")) + Dim hypGrafica As New HyperLink() + hypGrafica.NavigateUrl = "javascript:void(0);" + hypGrafica.Attributes.Add("onclick", "return generarGrafica('" & grid.ClientID & "');") + hypGrafica.CssClass = "grafica-icon" + hypGrafica.Controls.Add(New LiteralControl("")) + cellSucursal.Controls.Add(hypGrafica) + headerRow1.Cells.Add(cellSucursal) + + headerRow1.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(0, headerRow1) + + ' --- Fila 2 (Subheaders) --- + Dim headerRow2 As New GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Subheaders con checkboxes + headerRow2.Cells.Add(CreateSubHeaderCell("Año", "chkAño", "Año")) + headerRow2.Cells.Add(CreateSubHeaderCell("Mes", "chkMes", "Mes")) + headerRow2.Cells.Add(CreateSubHeaderCell("Semana", "chkSemana", "Semana")) + headerRow2.Cells.Add(CreateSubHeaderCell("Día", "chkDia", "Dia")) + + headerRow2.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(1, headerRow2) + End If + End Sub + + Protected Sub gvVentasPorVendedor_RowCreated(sender As Object, e As GridViewRowEventArgs) + If e.Row.RowType = DataControlRowType.Header Then + e.Row.Cells.Clear() + Dim grid As GridView = DirectCast(sender, GridView) + + ' --- Fila 1 --- + Dim headerRow1 As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Celda principal (Sucursal) + Dim cellSucursal As New TableHeaderCell() + cellSucursal.RowSpan = 2 + cellSucursal.VerticalAlign = VerticalAlign.Middle + cellSucursal.Controls.Add(New LiteralControl("Vendedor ")) + Dim hypGrafica As New HyperLink() + hypGrafica.NavigateUrl = "javascript:void(0);" + hypGrafica.Attributes.Add("onclick", "return generarGrafica('" & grid.ClientID & "');") + hypGrafica.CssClass = "grafica-icon" + hypGrafica.Controls.Add(New LiteralControl("")) + cellSucursal.Controls.Add(hypGrafica) + headerRow1.Cells.Add(cellSucursal) + + headerRow1.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(0, headerRow1) + + ' --- Fila 2 (Subheaders) --- + Dim headerRow2 As New GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Subheaders con checkboxes + headerRow2.Cells.Add(CreateSubHeaderCell("Año", "chkAño", "Año")) + headerRow2.Cells.Add(CreateSubHeaderCell("Mes", "chkMes", "Mes")) + headerRow2.Cells.Add(CreateSubHeaderCell("Semana", "chkSemana", "Semana")) + headerRow2.Cells.Add(CreateSubHeaderCell("Día", "chkDia", "Dia")) + + headerRow2.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(1, headerRow2) + End If + End Sub + + Protected Sub gvVentasPorClasificacion_RowCreated(sender As Object, e As GridViewRowEventArgs) + If e.Row.RowType = DataControlRowType.Header Then + e.Row.Cells.Clear() + Dim grid As GridView = DirectCast(sender, GridView) + + ' --- Fila 1 --- + Dim headerRow1 As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Celda principal (Sucursal) + Dim cellSucursal As New TableHeaderCell() + cellSucursal.RowSpan = 2 + cellSucursal.VerticalAlign = VerticalAlign.Middle + cellSucursal.Controls.Add(New LiteralControl("Clasificación ")) + Dim hypGrafica As New HyperLink() + hypGrafica.NavigateUrl = "javascript:void(0);" + hypGrafica.Attributes.Add("onclick", "return generarGrafica('" & grid.ClientID & "');") + hypGrafica.CssClass = "grafica-icon" + hypGrafica.Controls.Add(New LiteralControl("")) + cellSucursal.Controls.Add(hypGrafica) + headerRow1.Cells.Add(cellSucursal) + + headerRow1.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(0, headerRow1) + + ' --- Fila 2 (Subheaders) --- + Dim headerRow2 As New GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Subheaders con checkboxes + headerRow2.Cells.Add(CreateSubHeaderCell("Año", "chkAño", "Año")) + headerRow2.Cells.Add(CreateSubHeaderCell("Mes", "chkMes", "Mes")) + headerRow2.Cells.Add(CreateSubHeaderCell("Semana", "chkSemana", "Semana")) + headerRow2.Cells.Add(CreateSubHeaderCell("Día", "chkDia", "Dia")) + + headerRow2.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(1, headerRow2) + End If + End Sub + + Protected Sub gvVentasPorMarca_RowCreated(sender As Object, e As GridViewRowEventArgs) + If e.Row.RowType = DataControlRowType.Header Then + e.Row.Cells.Clear() + Dim grid As GridView = DirectCast(sender, GridView) + + ' --- Fila 1 --- + Dim headerRow1 As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Celda principal (Sucursal) + Dim cellSucursal As New TableHeaderCell() + cellSucursal.RowSpan = 2 + cellSucursal.VerticalAlign = VerticalAlign.Middle + cellSucursal.Controls.Add(New LiteralControl("Marca ")) + Dim hypGrafica As New HyperLink() + hypGrafica.NavigateUrl = "javascript:void(0);" + hypGrafica.Attributes.Add("onclick", "return generarGrafica('" & grid.ClientID & "');") + hypGrafica.CssClass = "grafica-icon" + hypGrafica.Controls.Add(New LiteralControl("")) + cellSucursal.Controls.Add(hypGrafica) + headerRow1.Cells.Add(cellSucursal) + + headerRow1.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(0, headerRow1) + + ' --- Fila 2 (Subheaders) --- + Dim headerRow2 As New GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Subheaders con checkboxes + headerRow2.Cells.Add(CreateSubHeaderCell("Año", "chkAño", "Año")) + headerRow2.Cells.Add(CreateSubHeaderCell("Mes", "chkMes", "Mes")) + headerRow2.Cells.Add(CreateSubHeaderCell("Semana", "chkSemana", "Semana")) + headerRow2.Cells.Add(CreateSubHeaderCell("Día", "chkDia", "Dia")) + + headerRow2.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(1, headerRow2) + End If + End Sub + + Protected Sub gvVentasPorPS_RowCreated(sender As Object, e As GridViewRowEventArgs) + If e.Row.RowType = DataControlRowType.Header Then + e.Row.Cells.Clear() + Dim grid As GridView = DirectCast(sender, GridView) + + ' --- Fila 1 --- + Dim headerRow1 As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Celda principal (Sucursal) + Dim cellSucursal As New TableHeaderCell() + cellSucursal.RowSpan = 2 + cellSucursal.VerticalAlign = VerticalAlign.Middle + cellSucursal.Controls.Add(New LiteralControl("PS ")) + Dim hypGrafica As New HyperLink() + hypGrafica.NavigateUrl = "javascript:void(0);" + hypGrafica.Attributes.Add("onclick", "return generarGrafica('" & grid.ClientID & "');") + hypGrafica.CssClass = "grafica-icon" + hypGrafica.Controls.Add(New LiteralControl("")) + cellSucursal.Controls.Add(hypGrafica) + headerRow1.Cells.Add(cellSucursal) + + headerRow1.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(0, headerRow1) + + ' --- Fila 2 (Subheaders) --- + Dim headerRow2 As New GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Subheaders con checkboxes + headerRow2.Cells.Add(CreateSubHeaderCell("Año", "chkAño", "Año")) + headerRow2.Cells.Add(CreateSubHeaderCell("Mes", "chkMes", "Mes")) + headerRow2.Cells.Add(CreateSubHeaderCell("Semana", "chkSemana", "Semana")) + headerRow2.Cells.Add(CreateSubHeaderCell("Día", "chkDia", "Dia")) + + headerRow2.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(1, headerRow2) + End If + End Sub + + Protected Sub gvVentasPorCliente_RowCreated(sender As Object, e As GridViewRowEventArgs) + If e.Row.RowType = DataControlRowType.Header Then + e.Row.Cells.Clear() + Dim grid As GridView = DirectCast(sender, GridView) + + ' --- Fila 1 --- + Dim headerRow1 As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Celda principal (Sucursal) + Dim cellSucursal As New TableHeaderCell() + cellSucursal.RowSpan = 2 + cellSucursal.VerticalAlign = VerticalAlign.Middle + cellSucursal.Controls.Add(New LiteralControl("Cliente ")) + Dim hypGrafica As New HyperLink() + hypGrafica.NavigateUrl = "javascript:void(0);" + hypGrafica.Attributes.Add("onclick", "return generarGrafica('" & grid.ClientID & "');") + hypGrafica.CssClass = "grafica-icon" + hypGrafica.Controls.Add(New LiteralControl("")) + cellSucursal.Controls.Add(hypGrafica) + headerRow1.Cells.Add(cellSucursal) + + headerRow1.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(0, headerRow1) + + ' --- Fila 2 (Subheaders) --- + Dim headerRow2 As New GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Subheaders con checkboxes + headerRow2.Cells.Add(CreateSubHeaderCell("Año", "chkAño", "Año")) + headerRow2.Cells.Add(CreateSubHeaderCell("Mes", "chkMes", "Mes")) + headerRow2.Cells.Add(CreateSubHeaderCell("Semana", "chkSemana", "Semana")) + headerRow2.Cells.Add(CreateSubHeaderCell("Día", "chkDia", "Dia")) + + headerRow2.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(1, headerRow2) + End If + End Sub + + Protected Sub gvVentasPorProveedor_RowCreated(sender As Object, e As GridViewRowEventArgs) + If e.Row.RowType = DataControlRowType.Header Then + e.Row.Cells.Clear() + Dim grid As GridView = DirectCast(sender, GridView) + + ' --- Fila 1 --- + Dim headerRow1 As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Celda principal (Sucursal) + Dim cellSucursal As New TableHeaderCell() + cellSucursal.RowSpan = 2 + cellSucursal.VerticalAlign = VerticalAlign.Middle + cellSucursal.Controls.Add(New LiteralControl("Proveedor ")) + Dim hypGrafica As New HyperLink() + hypGrafica.NavigateUrl = "javascript:void(0);" + hypGrafica.Attributes.Add("onclick", "return generarGrafica('" & grid.ClientID & "');") + hypGrafica.CssClass = "grafica-icon" + hypGrafica.Controls.Add(New LiteralControl("")) + cellSucursal.Controls.Add(hypGrafica) + headerRow1.Cells.Add(cellSucursal) + + headerRow1.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(0, headerRow1) + + ' --- Fila 2 (Subheaders) --- + Dim headerRow2 As New GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Subheaders con checkboxes + headerRow2.Cells.Add(CreateSubHeaderCell("Año", "chkAño", "Año")) + headerRow2.Cells.Add(CreateSubHeaderCell("Mes", "chkMes", "Mes")) + headerRow2.Cells.Add(CreateSubHeaderCell("Semana", "chkSemana", "Semana")) + headerRow2.Cells.Add(CreateSubHeaderCell("Día", "chkDia", "Dia")) + + headerRow2.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(1, headerRow2) + End If + End Sub + + Protected Sub gvCarteraPorSucursal_RowCreated(sender As Object, e As GridViewRowEventArgs) + If e.Row.RowType = DataControlRowType.Header Then + e.Row.Cells.Clear() + Dim grid As GridView = DirectCast(sender, GridView) + + ' --- Fila 1 --- + Dim headerRow1 As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Celda principal (Sucursal) + Dim cellSucursal As New TableHeaderCell() + cellSucursal.RowSpan = 2 + cellSucursal.VerticalAlign = VerticalAlign.Middle + cellSucursal.Controls.Add(New LiteralControl("Sucursal ")) + Dim hypGrafica As New HyperLink() + hypGrafica.NavigateUrl = "javascript:void(0);" + hypGrafica.Attributes.Add("onclick", "return generarGrafica('" & grid.ClientID & "');") + hypGrafica.CssClass = "grafica-icon" + hypGrafica.Controls.Add(New LiteralControl("")) + cellSucursal.Controls.Add(hypGrafica) + headerRow1.Cells.Add(cellSucursal) + + headerRow1.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(0, headerRow1) + + ' --- Fila 2 (Subheaders) --- + Dim headerRow2 As New GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Subheaders con checkboxes + headerRow2.Cells.Add(CreateSubHeaderCell("TotalCxC", "chkTotalCxC", "Total CxC")) + headerRow2.Cells.Add(CreateSubHeaderCell("Vencido", "chkVencido", "Vencido")) + headerRow2.Cells.Add(CreateSubHeaderCell("PorVencer", "chkPorVencer", "Por Vencer")) + + headerRow2.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(1, headerRow2) + End If + End Sub + + Protected Sub gvCarteraPorVendedor_RowCreated(sender As Object, e As GridViewRowEventArgs) + If e.Row.RowType = DataControlRowType.Header Then + e.Row.Cells.Clear() + Dim grid As GridView = DirectCast(sender, GridView) + + ' --- Fila 1 --- + Dim headerRow1 As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Celda principal (Sucursal) + Dim cellSucursal As New TableHeaderCell() + cellSucursal.RowSpan = 2 + cellSucursal.VerticalAlign = VerticalAlign.Middle + cellSucursal.Controls.Add(New LiteralControl("Vendedor ")) + Dim hypGrafica As New HyperLink() + hypGrafica.NavigateUrl = "javascript:void(0);" + hypGrafica.Attributes.Add("onclick", "return generarGrafica('" & grid.ClientID & "');") + hypGrafica.CssClass = "grafica-icon" + hypGrafica.Controls.Add(New LiteralControl("")) + cellSucursal.Controls.Add(hypGrafica) + headerRow1.Cells.Add(cellSucursal) + + headerRow1.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(0, headerRow1) + + ' --- Fila 2 (Subheaders) --- + Dim headerRow2 As New GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal) + + ' Subheaders con checkboxes + headerRow2.Cells.Add(CreateSubHeaderCell("TotalCxC", "chkTotalCxC", "Total CxC")) + headerRow2.Cells.Add(CreateSubHeaderCell("Vencido", "chkVencido", "Vencido")) + headerRow2.Cells.Add(CreateSubHeaderCell("PorVencer", "chkPorVencer", "Por Vencer")) + + headerRow2.TableSection = TableRowSection.TableHeader + grid.Controls(0).Controls.AddAt(1, headerRow2) + End If + End Sub + + ''' + ''' Ahora emitimos HTML puro para el checkbox + label, + ''' así el label realmente dispara el toggle del input. + ''' + Private Function CreateSubHeaderCell(text As String, checkboxId As String, dataField As String) As TableHeaderCell + Dim cell As New TableHeaderCell() + cell.HorizontalAlign = HorizontalAlign.Center + + ' Construimos un pequeño bloque HTML con y