diff --git a/App_Code/Timbrado.vb b/App_Code/Timbrado.vb index c50f0c354..48e9586ba 100644 --- a/App_Code/Timbrado.vb +++ b/App_Code/Timbrado.vb @@ -8,6 +8,7 @@ Imports System.Net.Http Imports System.Xml Imports System.Data Imports System.Xml.Serialization +Imports System.Net Public Class Timbrado @@ -495,6 +496,84 @@ Public Class Timbrado End If MsgCancelacion.AppendFormat("{0} --Código:{1} -- XML: {2}", objCan.MensajeError, objCan.CodigoError, objCan.Xml) + Case 5 + CancelacionAcuse = "" + Retorno = False + + MsgCancelacion.AppendFormat("5.1-") + Dim TimbraProduccion As Boolean = True + + Dim EmisorRFC As String = Empresa.RFC + Dim ArchivoLLave As String = $"{Empresa.Ruta}Certificados\{Empresa.ArchivoKey}" + Dim ArchivoCertificado As String = $"{Empresa.Ruta}Certificados\{Empresa.ArchivoCer}" + Dim Clave As String = Empresa.ContraseñaKey + + Dim UsuarioServicio As String = "rene.molina@adssistemas.mx" + Dim ClaveServicio As String = "Facturacion2021#" + + If Not Empresa.FacturaProduccion OrElse Empresa.CveEmpresa = 1 Then + EmisorRFC = "ZUÑ920208KL4" + ArchivoLLave = $"{Empresa.Ruta}Certificados\CSD01_ZUÑ920208KL4.key" + ArchivoCertificado = $"{Empresa.Ruta}Certificados\CSD01_ZUÑ920208KL4.cer" + Clave = "12345678a" + TimbraProduccion = False + End If + + Dim llaveByte As Byte(), certByte As Byte() + Dim llaveBase64 As String = "", certBase64 As String = "" + + Try + llaveByte = System.IO.File.ReadAllBytes(ArchivoLLave) + llaveBase64 = Convert.ToBase64String(llaveByte) + Catch ex As Exception + Alert($"Error al leer la llave privada: {ex.Message}", TipoMensaje.MsgError) + Return False + End Try + + Try + certByte = System.IO.File.ReadAllBytes(ArchivoCertificado) + certBase64 = Convert.ToBase64String(certByte) + Catch ex As Exception + Alert($"Error al leer el certificado: {ex.Message}", TipoMensaje.MsgError) + Return False + End Try + + Dim Contrato As String = "72330711-cac6-4106-8051-cbcda1aef495" + + Dim Respuesta As String = EnviarInformacionCancelacionPADESOAP("https://timbrado.pade.mx/servicio/Timbrado3.3?wsdl", UsuarioServicio, ClaveServicio, Contrato, EmisorRFC, RFCReceptor, certBase64, llaveBase64, Clave, FolioFiscal, Total, TimbraProduccion) + + If Not String.IsNullOrEmpty(Respuesta) Then + Dim result As PADEServicioCancelacionResp = Nothing + Dim serializer As XmlSerializer = New XmlSerializer(GetType(PADEServicioCancelacionResp)) + + Try + Using reader As TextReader = New StringReader(Respuesta) + result = CType(serializer.Deserialize(reader), PADEServicioCancelacionResp) + End Using + Catch ex As Exception + OnError("Ocurrió un error al obtener los resultados", ex) + End Try + + If result IsNot Nothing Then + If result.statusOk Then + Dim cancelacion = result.cancelaciones.First() + If cancelacion IsNot Nothing Then + 'EN PROCESO, CANCELABLE SIN ACEPTACION,CANCEALDO PREVIAMENTE + If cancelacion.codigo.Contiene("96", "201", "202") Then + CancelacionFecha = Now + Retorno = True + CancelacionAcuse = result.acuseCancelBase64 + End If + CancelacionMensaje = cancelacion.mensaje + Else + CancelacionMensaje = result.mensaje + End If + + End If + End If + Else + + End If End Select @@ -504,6 +583,99 @@ Public Class Timbrado Return Retorno End Function + + + Public Class PADEServicioCancelacionResp + + Public Property statusOk As Boolean + + Public Property codigo As String + + Public Property mensaje As String + + Public Property procesados As Integer + + Public Property cancelados As Integer + + + Public Property cancelaciones As List(Of PADECancelacion) + + Public Property acuseCancelBase64 As String + End Class + + + Public Class PADECancelacion + + Public Property uuid As String + + Public Property codigo As String + + Public Property mensaje As String + End Class + + Private Function EnviarInformacionCancelacionPADESOAP(ByVal url As String, UsuarioServicio As String, PassServicio As String, contrato As String, rfcEmisor As String, rfcReceptor As String, + certBase64 As String, keyBase64 As String, keyPass As String, arregloUUID As String, Total As Decimal, TimbraProduccion As Boolean) As String + Dim retorno = "" + Try + + Dim request As HttpWebRequest = CType(WebRequest.Create($"{url}"), HttpWebRequest) + 'request.Headers.Add("SOAPAction:http://tempuri.org/TestCfd33 ") + request.ContentType = "text/xml;charset=""utf-8""" + request.Accept = "text/xml" + request.Method = "POST" + + Dim XMLString As String = $" + + + {contrato} + {UsuarioServicio} + {PassServicio} + {rfcEmisor} + {arregloUUID}|{rfcReceptor}|{rfcEmisor}|{Total} + {certBase64} + {keyBase64} + {keyPass} + {If(TimbraProduccion, "", "MODO_PRUEBA:3")} + + + " + + Dim SOAPReqBody As XmlDocument = New XmlDocument() + SOAPReqBody.LoadXml(XMLString) + + Using stream As Stream = request.GetRequestStream() + SOAPReqBody.Save(stream) + End Using + + Dim response As String = "" + + Using Serviceres As WebResponse = request.GetResponse() + Using rd As StreamReader = New StreamReader(Serviceres.GetResponseStream()) + response = rd.ReadToEnd() + End Using + End Using + + If Not String.IsNullOrEmpty(response) Then + Dim xmlRetorno = New XmlDocument() + xmlRetorno.LoadXml(response) + Dim elemList As XmlNodeList = xmlRetorno.GetElementsByTagName("return") + + If elemList.Count > 0 Then + If elemList(0).ChildNodes.Count > 0 Then + retorno = elemList(0).ChildNodes(0).Value + End If + End If + + End If + + Catch ex As Exception + retorno = "" + OnError("Ocurrió un error al cancelar", ex) + End Try + + Return retorno + End Function + Public Function PreparaTimbrePago(EmisorRFC As String, EmisorNombre As String, EmisorRegimenFiscal As String, ReceptorRFC As String, ReceptorNombre As String, Serie As String, Folio As String, FechaTimbrado As DateTime, CuentaPago As String, FechaPago As DateTime, FormaPago As String, MonedaPago As String, Monto As Double, LugarExpedicion As String, @@ -2026,19 +2198,19 @@ Public Class Timbrado If ObjCFDITimbre.Nomina IsNot Nothing Then 'If cfdi.Nomina12SeparacionIndemnizacion Then If ObjCFDITimbre.Nomina.Percepciones IsNot Nothing AndAlso ObjCFDITimbre.Nomina.Percepciones.Count > 0 Then - cfdi.Nomina12Percepciones(ObjCFDITimbre.Nomina.TotalSueldos, ObjCFDITimbre.Nomina.TotalIndemnizacion, ObjCFDITimbre.Nomina.TotalJubilacion, ObjCFDITimbre.Nomina.TotalPercepcionesGravado, ObjCFDITimbre.Nomina.TotalPercepcionesExento) - For Each percep As CFDINominaPercepciones In ObjCFDITimbre.Nomina.Percepciones - cfdi.Nomina12Percepcion(percep.TipoPercepcion, percep.Clave, percep.Concepto, Math.Round(percep.ImporteGravado, 2), Math.Round(percep.ImporteExento, 2)) - If percep.TipoPercepcion.ToEntero() = 19 Then + cfdi.Nomina12Percepciones(ObjCFDITimbre.Nomina.TotalSueldos, ObjCFDITimbre.Nomina.TotalIndemnizacion, ObjCFDITimbre.Nomina.TotalJubilacion, ObjCFDITimbre.Nomina.TotalPercepcionesGravado, ObjCFDITimbre.Nomina.TotalPercepcionesExento) + For Each percep As CFDINominaPercepciones In ObjCFDITimbre.Nomina.Percepciones + cfdi.Nomina12Percepcion(percep.TipoPercepcion, percep.Clave, percep.Concepto, Math.Round(percep.ImporteGravado, 2), Math.Round(percep.ImporteExento, 2)) + If percep.TipoPercepcion.ToEntero() = 19 Then - If ObjCFDITimbre.Nomina.HorasExtras IsNot Nothing AndAlso ObjCFDITimbre.Nomina.HorasExtras.Count > 0 Then - For Each HoraExtra As CFDINominaHorasExtras In ObjCFDITimbre.Nomina.HorasExtras - cfdi.Nomina12HorasExtra(HoraExtra.Dias.ToEntero, HoraExtra.TipoHoras, HoraExtra.HorasExtra, HoraExtra.ImportePagado) - Next - End If + If ObjCFDITimbre.Nomina.HorasExtras IsNot Nothing AndAlso ObjCFDITimbre.Nomina.HorasExtras.Count > 0 Then + For Each HoraExtra As CFDINominaHorasExtras In ObjCFDITimbre.Nomina.HorasExtras + cfdi.Nomina12HorasExtra(HoraExtra.Dias.ToEntero, HoraExtra.TipoHoras, HoraExtra.HorasExtra, HoraExtra.ImportePagado) + Next End If - Next - End If + End If + Next + End If If ObjCFDITimbre.IStimbreFiniquito Then 'ObjCFDITimbre.Nomina. @@ -2051,39 +2223,39 @@ Public Class Timbrado End If 'deducciones al final If ObjCFDITimbre.Nomina.Deducciones IsNot Nothing AndAlso ObjCFDITimbre.Nomina.Deducciones.Count > 0 Then - cfdi.Nomina12Deducciones(ObjCFDITimbre.Nomina.TotalDeduccionesOtras, Math.Round(ObjCFDITimbre.Nomina.TotalDeduccionesImpuestosRetenidos, 2)) - For Each deduc As CFDINominaDeducciones In ObjCFDITimbre.Nomina.Deducciones - cfdi.Nomina12Deduccion(deduc.TipoDeduccion, deduc.Clave, deduc.Concepto, Math.Round(deduc.Importe, 2)) - Next - End If - If ObjCFDITimbre.Nomina.OtrosPagos IsNot Nothing Then - ' cfdi.agregarNominaOtrosPagosOtroPago12("002", "002", "Subsidio", "10.00"); - ' cfdi.agregarNominaOtrosPagosOtroPagoSubsidioAlEmpleo12("10.00"); - If ObjCFDITimbre.Nomina.OtrosPagos IsNot Nothing AndAlso ObjCFDITimbre.Nomina.OtrosPagos.Count > 0 Then - For Each otpag As CFDINominaOtrosPagos In ObjCFDITimbre.Nomina.OtrosPagos - cfdi.Nomina12OtroPago(otpag.TipoOtroPago, otpag.Clave, otpag.Concepto, otpag.Importe) - If otpag.TipoOtroPago = "002" Then - cfdi.Nomina12SubsidioAlEmpleo(otpag.Subsidiocausado) - End If + cfdi.Nomina12Deducciones(ObjCFDITimbre.Nomina.TotalDeduccionesOtras, Math.Round(ObjCFDITimbre.Nomina.TotalDeduccionesImpuestosRetenidos, 2)) + For Each deduc As CFDINominaDeducciones In ObjCFDITimbre.Nomina.Deducciones + cfdi.Nomina12Deduccion(deduc.TipoDeduccion, deduc.Clave, deduc.Concepto, Math.Round(deduc.Importe, 2)) + Next + End If + If ObjCFDITimbre.Nomina.OtrosPagos IsNot Nothing Then + ' cfdi.agregarNominaOtrosPagosOtroPago12("002", "002", "Subsidio", "10.00"); + ' cfdi.agregarNominaOtrosPagosOtroPagoSubsidioAlEmpleo12("10.00"); + If ObjCFDITimbre.Nomina.OtrosPagos IsNot Nothing AndAlso ObjCFDITimbre.Nomina.OtrosPagos.Count > 0 Then + For Each otpag As CFDINominaOtrosPagos In ObjCFDITimbre.Nomina.OtrosPagos + cfdi.Nomina12OtroPago(otpag.TipoOtroPago, otpag.Clave, otpag.Concepto, otpag.Importe) + If otpag.TipoOtroPago = "002" Then + cfdi.Nomina12SubsidioAlEmpleo(otpag.Subsidiocausado) + End If - If otpag.TipoOtroPago = "004" AndAlso otpag.Importe > 0 Then - If otpag.ejercicio > 0 Then - cfdi.CompensacionSaldosAFavor(otpag.SaldoAFavor, otpag.ejercicio, otpag.RemanenteSalFav) 'otpag.SaldoAFavor - End If + If otpag.TipoOtroPago = "004" AndAlso otpag.Importe > 0 Then + If otpag.ejercicio > 0 Then + cfdi.CompensacionSaldosAFavor(otpag.SaldoAFavor, otpag.ejercicio, otpag.RemanenteSalFav) 'otpag.SaldoAFavor End If + End If - Next - End If - End If - If ObjCFDITimbre.Nomina.Incapacidades IsNot Nothing AndAlso ObjCFDITimbre.Nomina.Incapacidades.Count > 0 Then - For Each Incap As CFDINominaIncapacidades In ObjCFDITimbre.Nomina.Incapacidades - cfdi.Nomina12Incapacidad(Incap.DiasIncapacidad.ToEntero, Incap.TipoIncapacidad, Incap.Importe) Next End If End If + If ObjCFDITimbre.Nomina.Incapacidades IsNot Nothing AndAlso ObjCFDITimbre.Nomina.Incapacidades.Count > 0 Then + For Each Incap As CFDINominaIncapacidades In ObjCFDITimbre.Nomina.Incapacidades + cfdi.Nomina12Incapacidad(Incap.DiasIncapacidad.ToEntero, Incap.TipoIncapacidad, Incap.Importe) + Next + End If + End If #End Region - sw.Stop() + sw.Stop() swTiempo.AppendFormat("Armado: ({0}) {1} ", sw.ElapsedMilliseconds - swmili, sw.ElapsedMilliseconds) swmili = sw.ElapsedMilliseconds sw.Start() @@ -2683,27 +2855,27 @@ Public Class Timbrado swmili = sw.ElapsedMilliseconds sw.Start() + Dim msgErrorGeneracion As String = If(String.IsNullOrEmpty(cfdi.MensajeError), "", cfdi.MensajeError) + #Region "Timbra" If ArchivoGenerado Then - 'Dim opciones As String() = New String(0) {""} - 'Dim pade = New PADETimbrado.PadeTimbradoServiceClient + Dim Respuesta As String = "" - 'Dim Respuesta As String = pade.timbradoConCSD("72330711-cac6-4106-8051-cbcda1aef495", UsuarioServicio, ClaveServicio, cfdi.Xml, certByte, llaveByte, Clave, Not TimbraProduccion, opciones) + If String.IsNullOrEmpty(msgErrorGeneracion) Then + Dim TokenAuth As String = $"{UsuarioServicio}:{ClaveServicio}".ToBase64Encode() - Dim TokenAuth As String = $"{UsuarioServicio}:{ClaveServicio}".ToBase64Encode() - - Dim payload As New JObject( - New JProperty("contrato", "72330711-cac6-4106-8051-cbcda1aef495"), - New JProperty("certBase64", certBase64), - New JProperty("keyBase64", llaveBase64), - New JProperty("keyPass", Clave), - New JProperty("xmlBase64", cfdi.Xml.ToBase64Encode()), - New JProperty("prueba", (Not TimbraProduccion).ToString().ToLower), - New JProperty("opciones", New String(0) {""}) - ) - - Dim Respuesta = EnviarInformacionPADE("https://timbrado.pade.mx/servicio/rest/timbrado/timbrarConCSD", payload.ToString(), TokenAuth) + Dim payload As New JObject( + New JProperty("contrato", "72330711-cac6-4106-8051-cbcda1aef495"), + New JProperty("certBase64", certBase64), + New JProperty("keyBase64", llaveBase64), + New JProperty("keyPass", Clave), + New JProperty("xmlBase64", cfdi.Xml.ToBase64Encode()), + New JProperty("prueba", (Not TimbraProduccion).ToString().ToLower), + New JProperty("opciones", New String(0) {""}) + ) + Respuesta = EnviarInformacionPADE("https://timbrado.pade.mx/servicio/rest/timbrado/timbrarConCSD", payload.ToString(), TokenAuth) + End If ' Aumentamos el timeout de la operación If Not String.IsNullOrEmpty(Respuesta) Then @@ -2722,8 +2894,8 @@ Public Class Timbrado If result IsNot Nothing Then If result.timbradoOk Then Dim FolioFiscal As String = result.UUID - - cfdi.EscribirXML(cfdi.Xml, RutaArchivo, NombreArchivoXML) + 'GUARDA EL XML RETORNADO POR EL PAC + cfdi.EscribirXML(result.xmlBase64.ToBase64Decode(), RutaArchivo, NombreArchivoXML) If ObjCFDITimbre.Comprobante.TipoComprobante <> "P" Then @@ -2786,14 +2958,13 @@ Public Class Timbrado Retorno = "" Else If String.IsNullOrEmpty(result.mensaje) Then - Retorno = Respuesta + Retorno = Respuesta + msgErrorGeneracion MensajeErrorCFDI = "" Else Retorno = result.mensaje MensajeErrorCFDI = result.codigo If cfdi.Xml <> "" Then cfdi.EscribirXML(cfdi.Xml, RutaArchivo, NombreArchivoXML) End If - End If Else If String.IsNullOrEmpty(Respuesta) Then @@ -2805,12 +2976,22 @@ Public Class Timbrado End If End If Else - Retorno = "Ocurrió un error al obtener la respuesta" - MensajeErrorCFDI = "" + If String.IsNullOrEmpty(msgErrorGeneracion) Then + Retorno = "Ocurrió un error al obtener la respuesta" + MensajeErrorCFDI = "" + Else + Retorno = msgErrorGeneracion + MensajeErrorCFDI = "" + End If End If Else - Retorno = "Ocurrió un error al generar el xml" - MensajeErrorCFDI = "" + If String.IsNullOrEmpty(msgErrorGeneracion) Then + Retorno = "Ocurrió un error al generar el xml" + MensajeErrorCFDI = "" + Else + Retorno = msgErrorGeneracion + MensajeErrorCFDI = "" + End If End If #End Region @@ -2854,6 +3035,10 @@ Public Class Timbrado Public Property mensaje As String Public Property UUID As String + + Public Property FechaTimbrado As DateTime + + Public Property xmlBase64 As String End Class @@ -2907,9 +3092,13 @@ Public Class Timbrado UsuarioServicio = "fgomez" ClaveServicio = "12121212" Clave = "12345678a" - EmisorRFC = "AAA010101AAA" - ArchivoLLave = $"{UsuarioActual.Empresa.Ruta}Certificados\CSD01_AAA010101AAA.key" - ArchivoCertificado = $"{UsuarioActual.Empresa.Ruta}Certificados\CSD01_AAA010101AAA.cer" + 'EmisorRFC = "AAA010101AAA" + 'ArchivoLLave = $"{UsuarioActual.Empresa.Ruta}Certificados\CSD01_AAA010101AAA.key" + 'ArchivoCertificado = $"{UsuarioActual.Empresa.Ruta}Certificados\CSD01_AAA010101AAA.cer" + EmisorRFC = "ZUÑ920208KL4" + ArchivoLLave = $"{UsuarioActual.Empresa.Ruta}Certificados\CSD01_ZUÑ920208KL4.key" + ArchivoCertificado = $"{UsuarioActual.Empresa.Ruta}Certificados\CSD01_ZUÑ920208KL4.cer" + UrlServicio = "http://generacfdi.com.mx/rvltimbrado/service1.asmx?WSDL" '"http://108.60.211.43/rvltimbrado/service1.asmx" End If