diff --git a/AF/AF.aspx.vb b/AF/AF.aspx.vb
index 965f8e168..cdfbb7d58 100644
--- a/AF/AF.aspx.vb
+++ b/AF/AF.aspx.vb
@@ -2690,6 +2690,7 @@ Partial Class AF_AF
Try
+ 'Dim Para As String = "roberto.hernandez@exploracionesmineras.com"
Dim Para As String = "oscar.irigoyen@adssistemas.mx"
Dim Asunto As String = $"Registro de {If(Opcion = 1, "Alta de Activo Fijo", "Baja de ActivoFijo")}"
Dim Body As String = ""
@@ -2717,7 +2718,7 @@ Partial Class AF_AF
strBody.Append("
")
strBody.Append($"{If(Opcion = 1, "Alta de Activo Fijo", "Baja de Activo Fijo")}
")
strBody.Append("")
- strBody.Append("| Campo | Valor |
")
+ 'strBody.Append("| Campo | Valor |
")
strBody.Append($"| Código | {Codigo} |
")
strBody.Append($"| Descripción | {Descripcion} |
")
strBody.Append($"| Proyecto | {Proyecto} |
")
diff --git a/Bancos/PagoElectronicoGrupos.aspx.vb b/Bancos/PagoElectronicoGrupos.aspx.vb
index 245d7a2e0..3d7cbcf63 100644
--- a/Bancos/PagoElectronicoGrupos.aspx.vb
+++ b/Bancos/PagoElectronicoGrupos.aspx.vb
@@ -2,8 +2,9 @@
Option Strict On
Imports System.Data
-Imports Extensiones
+Imports System.Globalization
Imports System.IO
+Imports Extensiones
Imports Ionic.Zip
Imports Microsoft.Reporting.WebForms
@@ -1167,12 +1168,34 @@ Partial Class Bancos_PagoElectronicoGrupos
If Not DdlCuenta.SelectedValue.ToEntero > 0 Then
Alert("Primero debe seleccionar una Cuenta", TipoMensaje.MsgAdvertencia)
Exit Sub
- End If
-
+ End If
+
+
+ 'GlobalDTBancosCuentas.FiltraParametros($"CveCuentaDeposito = {DdlCuenta.SelectedValue} AND EstatusCtaDeposito = 'True'")
+
+
+
If DTPendientes.FiltraParametros("EstatusPagoElectronicoGrupos = 'True' AND EstatusCtaDeposito = 'True'") IsNot Nothing Then
- GeneraPago(DTPendientes.FiltraParametros("EstatusPagoElectronicoGrupos = 'True' AND EstatusCtaDeposito > 0"))
-
+ Dim CuentaCargo As String = "0382755740201"
+
+ If DdlCuenta.SelectedItem.Text.Contains("BAJIO") Then
+
+ GeneraPagoBajio(
+ numeroArchivo:=1,
+ fechaCargo:=NowADS,
+ cuentaCargo:=CuentaCargo,
+ DTPendientes.FiltraParametros("EstatusPagoElectronicoGrupos = 'True' AND EstatusCtaDeposito > 0"))
+
+
+ ElseIf DdlCuenta.SelectedItem.Text.Contains("Scotiabank") Then
+ GeneraPagoScotiabank(DTPendientes.FiltraParametros("EstatusPagoElectronicoGrupos = 'True' AND EstatusCtaDeposito > 0"))
+ Else
+ GeneraPago(DTPendientes.FiltraParametros("EstatusPagoElectronicoGrupos = 'True' AND EstatusCtaDeposito > 0"))
+ End If
+
+
+
Else
Alert("No hay registros para generar", TipoMensaje.MsgAdvertencia)
@@ -1180,6 +1203,175 @@ Partial Class Bancos_PagoElectronicoGrupos
End If
End Sub
+ 'Private Sub GeneraPagoBajio(dataTable As DataTable)
+ ' 'Throw New NotImplementedException()
+ 'End Sub
+
+ Public Sub GeneraPagoBajio(numeroArchivo As Integer,
+ fechaCargo As Date,
+ cuentaCargo As String,
+ DTDatos As DataTable)
+
+
+ Dim HEADER_LEN As Integer = 20
+ Dim DETALLE_LEN As Integer = 384
+ Dim TRAILER_LEN As Integer = 34
+
+ ' --- columnas fijas del header / trailer ---
+ Dim DIVISA_MXN As String = "001"
+ Dim FILLER_8CEROS As String = "00000000"
+ Dim FILLER_4CEROS As String = "0000"
+ Dim CONST_0140 As String = "0140" '/** Pregunta */: tu banco usa siempre 0140?
+
+ Dim _mediosValidos As HashSet(Of String) = New HashSet(Of String)({"BCO", "TEF", "SPE", "SPD"})
+ Dim _tiposCuentaValidos As HashSet(Of String) = New HashSet(Of String)({"40", "1", "3"})
+
+ ' --------------------------- Header (20 bytes) ---------------------------
+ Dim header As String = $"01{numeroArchivo:D7}{fechaCargo:yyyyMMdd}{DIVISA_MXN}"
+ If header.Length <> HEADER_LEN Then
+ Alert($"Header debe medir {HEADER_LEN} bytes, mide {header.Length}.", TipoMensaje.MsgAdvertencia)
+ Exit Sub
+ End If
+
+ ' --------------------------- Detalles (384 bytes) ------------------------
+ Dim detalles As New List(Of String)(DTDatos.Rows.Count)
+ Dim consecArchivo As Integer = 2 'el #1 lo ocupa el header
+ Dim consecPago As Integer = 1
+ Dim totalCentavos As Long = 0
+ Dim MedioPago As String = "TEF"
+ Dim ReferenciaSPEI As String = ""
+ Dim ClasificacionSPID As String = ""
+
+
+ For Each DRow As DataRow In DTDatos.Rows
+
+ Dim ClabeOCuenta As String = DRow("CLABEDestino").ToString.Trim
+ Dim nCaracteresClabeCuenta As Integer = ClabeOCuenta.Length
+ Dim TipoCuentaDestino As String = ""
+ Dim Importe As Decimal = DRow("Importe").ToString.ToDecimal
+ Dim IVA As Decimal = 0D
+
+ If nCaracteresClabeCuenta <> 18 Then
+ If nCaracteresClabeCuenta <> 12 Then
+ Alert($"CLABE/Cuenta debe tener 18 o 12 caracteres, tiene {ClabeOCuenta.Length}.", TipoMensaje.MsgAdvertencia)
+ Exit Sub
+ End If
+ End If
+
+ If nCaracteresClabeCuenta = 18 Then
+ TipoCuentaDestino = "40"
+ Else
+ TipoCuentaDestino = "1"
+ End If
+
+
+ ' ----------- Validaciones de negocio --------------------------------
+ DRow("RazonSocial") = LimpiarDatosBajio(DRow("RazonSocial").ToString, 15, "Alias")
+ DRow("RazonSocial") = LimpiarDatosBajio(DRow("RazonSocial").ToString, 250, "Descripción")
+
+ If Not _tiposCuentaValidos.Contains(TipoCuentaDestino) Then
+ Alert($"TipoCuentaDestino inválido: {TipoCuentaDestino}", TipoMensaje.MsgAdvertencia)
+ Exit Sub
+ End If
+
+ If Not _mediosValidos.Contains(MedioPago) Then
+ Alert($"MedioPago inválido: {MedioPago}", TipoMensaje.MsgAdvertencia)
+ Exit Sub
+ End If
+
+ If MedioPago = "SPE" AndAlso (ReferenciaSPEI.Length <> 7 OrElse Not IsNumeric(ReferenciaSPEI)) Then
+ Alert("ReferenciaSPEI debe contener 7 dígitos numéricos cuando MedioPago = SPE.", TipoMensaje.MsgAdvertencia)
+ Exit Sub
+ End If
+
+ If MedioPago <> "SPD" AndAlso Not String.IsNullOrEmpty(ClasificacionSPID) Then
+ Alert("ClasificacionSPID sólo se permite cuando MedioPago = SPD.", TipoMensaje.MsgAdvertencia)
+ Exit Sub
+ End If
+
+ If Importe <= 0D Then
+ Alert("Importe debe ser mayor a cero.", TipoMensaje.MsgAdvertencia)
+ Exit Sub
+ End If
+
+ 'If DRow.IVA < 0D Then
+ ' Alert("IVA no puede ser negativo.", TipoMensaje.MsgAdvertencia)
+ ' Exit Sub
+ 'End If
+
+ ' ----------- Construcción de la línea --------------------------------
+ Dim sb As New StringBuilder(DETALLE_LEN)
+
+ sb.Append("02") 'tipo registro
+ sb.Append(consecArchivo.ToString("D7")) 'consec archivo
+ sb.Append("01") 'tipo cta origen fijo
+ sb.Append(FILLER_8CEROS) 'filler
+ sb.Append(cuentaCargo.PadLeft(12, "0"c)) 'cta cargo
+ sb.Append(CONST_0140) 'constante 0140
+ sb.Append(ClabeOCuenta.PadLeft(3, "0"c))
+ sb.Append("00") '5 dígitos banco destino
+ sb.Append(consecPago.ToString("D10")) 'consec pago
+ sb.Append("000" & fechaCargo.ToString("yyyyMMdd")) 'prefijo 000 + fecha
+ sb.Append(MedioPago) 'BCO/TEF/SPE/SPD
+ sb.Append(TipoCuentaDestino.PadLeft(2, "0"c)) 'tipo cta destino
+ sb.Append(FILLER_4CEROS) 'filler
+ sb.Append(DRow("RazonSocial").ToString.PadRight(15)) 'alias (15)
+ sb.Append(CLng(IVA).ToString("D15")) 'IVA ×100
+ sb.Append(DRow("RazonSocial").ToString.PadRight(250)) 'descripción (250)
+ sb.Append(If(String.IsNullOrEmpty(ReferenciaSPEI),
+ New String("0"c, 7),
+ ReferenciaSPEI)) 'referencia SPEI
+ sb.Append(If(String.IsNullOrEmpty(ClasificacionSPID),
+ "00",
+ ClasificacionSPID.PadLeft(2, "0"c))) 'clasif SPID
+ sb.Append(New String(" "c, 25)) 'filler final
+
+ If sb.Length <> DETALLE_LEN Then
+ Throw New InvalidOperationException($"Detalle #{consecPago} mide {sb.Length} bytes, debería {DETALLE_LEN}.")
+ End If
+
+ detalles.Add(sb.ToString())
+ consecArchivo += 1
+ consecPago += 1
+ totalCentavos += CLng(Importe * 100)
+ Next
+
+ ' --------------------------- Trailer (34 bytes) -------------------------
+ Dim totalLineas As Integer = 1 + DTDatos.Rows.Count + 1 'header + detalles + trailer
+ Dim trailer As String = $"09{totalLineas:D7}{DTDatos.Rows.Count:D7}{FILLER_8CEROS}{totalCentavos:D10}"
+ If trailer.Length <> TRAILER_LEN Then Throw New InvalidOperationException($"Trailer debe medir {TRAILER_LEN} bytes, mide {trailer.Length}.")
+
+ ' --------------------------- Resultado ----------------------------------
+ 'Return {header}.Concat(detalles).Concat({trailer})
+ End Sub
+
+ Private Function LimpiarDatosBajio(texto As String, maxLen As Integer, campo As String) As String
+
+ Dim _rxProhibidos As Regex = New Regex("[\$\,\./\-ñÑÁÉÍÓÚÜáéíóúü]", RegexOptions.Compiled)
+
+ If String.IsNullOrWhiteSpace(texto) Then
+ Throw New ArgumentException($"{campo} es obligatorio.")
+ End If
+
+ ' Normalizar y quitar diacríticos
+ Dim s = New String(texto.Normalize(NormalizationForm.FormD) _
+ .Where(Function(ch) CharUnicodeInfo.GetUnicodeCategory(ch) <> UnicodeCategory.NonSpacingMark) _
+ .ToArray()) _
+ .Normalize(NormalizationForm.FormC)
+
+ ' Eliminar caracteres prohibidos
+ s = _rxProhibidos.Replace(s, "")
+
+ If s.Length > maxLen Then
+ Throw New ArgumentException($"{campo} ({s}) excede {maxLen} caracteres.")
+ End If
+ Return s
+ End Function
+
+ Private Sub GeneraPagoScotiabank(dataTable As DataTable)
+ 'Throw New NotImplementedException()
+ End Sub
+
Private Sub GeneraPago(DTPendientesTemp As DataTable, Optional InsertaEnDB As Boolean = True, Optional NombreArchivoEnviado As String = "")
Dim RegistrosPago As New StringBuilder
diff --git a/Compras/Compras.aspx.vb b/Compras/Compras.aspx.vb
index 505f8942e..8b1947ecb 100644
--- a/Compras/Compras.aspx.vb
+++ b/Compras/Compras.aspx.vb
@@ -18116,6 +18116,9 @@ Partial Class Compras_Compras
DdlIVA.Enabled = True
End If
+ If UsuarioActual.CveRol = 1 Then
+ TxtRetISRModal.Enabled = True
+ End If
UpPSS.Update()
RegistraScript("$('#divAddProducto').modal('show');")
diff --git a/Compras/eFacturas.aspx.vb b/Compras/eFacturas.aspx.vb
index 7176a8e4e..6d6c56058 100644
--- a/Compras/eFacturas.aspx.vb
+++ b/Compras/eFacturas.aspx.vb
@@ -1756,9 +1756,7 @@ Partial Class Compras_eFacturas
Dim PDfDestino As String = $"{UsuarioActual.Empresa.Ruta}\Compras\{FF.EmisorRFC}\{FF.CveFactura}.PDF"
- If RutaPDF = "" Then
-
-
+ If RutaPDF = "" Then ' llega sin pdf
'no valida nada solo lo crea y lo pone en la carpeta, no importa si ya existe
If SobreEscribirPDFSiExiste Then
@@ -9124,6 +9122,12 @@ Namespace ADS.eFacturas
Dim TmpArchivoQR As String = $"{Ruta}\Temp\Facturas\{Path.GetFileNameWithoutExtension(Fact.ArchivoXML)}-ttt.jpg"
Dim ArchivoXML As String = String.Format("{0}\Compras\{2}\{1}", DirectorioEmpresa, Fact.ArchivoXML, Fact.EmisorRFC)
Dim ArchivoPDF As String = String.Format("{0}\Compras\{2}\{1}.pdf", DirectorioEmpresa, Fact.CveFactura, Fact.EmisorRFC)
+
+ 'Validación si existe PDF no lo genera
+ If System.IO.File.Exists(ArchivoPDF) Then
+ Return True
+ End If
+
Dim dtotal As Decimal = If(Fact.Total <= 0.0D, 0.0001D, Fact.Total)
Dim cfdi As New RVCFDI33.GeneraCFDI()