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("") + 'strBody.Append("") strBody.Append($"") strBody.Append($"") strBody.Append($"") 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()
CampoValor
CampoValor
Código{Codigo}
Descripción{Descripcion}
Proyecto{Proyecto}