- mejora
This commit is contained in:
@@ -1,9 +1,20 @@
|
||||
Option Explicit On
|
||||
Option Strict On
|
||||
|
||||
Imports System.Data
|
||||
Imports System.IO
|
||||
Imports Extensiones
|
||||
Imports System
|
||||
Imports System.IO
|
||||
Imports System.Security.Cryptography
|
||||
Imports System.Security.Cryptography.X509Certificates
|
||||
Imports System.Text
|
||||
Imports System.Xml
|
||||
Imports System.Xml.Xsl
|
||||
Imports System.Data
|
||||
Imports CrystalDecisions.Web
|
||||
Imports DocumentFormat.OpenXml.Wordprocessing
|
||||
Imports Org.BouncyCastle.Asn1
|
||||
Imports Org.BouncyCastle.Tls.Crypto.Impl
|
||||
|
||||
Partial Class Contabilidad_ContabilidadElectronica
|
||||
Inherits ClsPaginas
|
||||
|
||||
@@ -95,7 +106,7 @@ Partial Class Contabilidad_ContabilidadElectronica
|
||||
End If
|
||||
objconta.Dispose()
|
||||
Else
|
||||
Dim ObjConpaq As New ClsContPAQi(UsuarioActual.Empresa)
|
||||
Dim ObjConpaq As New ClsContPAQi(UsuarioActual.Empresa)
|
||||
If ObjConpaq.GetCuentasElectronica(MinFecha, FechaF) Then
|
||||
DtCuentas = ObjConpaq.DtResultados
|
||||
End If
|
||||
@@ -112,9 +123,6 @@ Partial Class Contabilidad_ContabilidadElectronica
|
||||
Str.AppendFormat("RFC=""{0}"" ", UsuarioActual.Empresa.RFC)
|
||||
Str.AppendFormat("Mes=""{0}"" ", DdlPeriodo.SelectedValue)
|
||||
Str.AppendFormat("Anio=""{0}"" ", DdlEjercicio.SelectedValue)
|
||||
Str.AppendFormat("Sello=""{0}"" ", "123")
|
||||
Str.AppendFormat("noCertificado=""{0}"" ", "123")
|
||||
Str.AppendFormat("Certificado=""{0}"" ", "1234567890")
|
||||
Str.Append("xmlns:catalogocuentas=""www.sat.gob.mx/esquemas/ContabilidadE/1_3/CatalogoCuentas"">")
|
||||
|
||||
'DETALLES
|
||||
@@ -147,21 +155,15 @@ Partial Class Contabilidad_ContabilidadElectronica
|
||||
ArchivoCuentas = $"{UsuarioActual.Empresa.Ruta}/ContabilidadElectronica/{ UsuarioActual.Empresa.RFC}{DdlEjercicio.SelectedValue}{DdlPeriodo.SelectedValue.PadLeft(2, "0"c)}CT.xml"
|
||||
|
||||
'SOBREESCRIBE
|
||||
If System.IO.File.Exists(ArchivoCuentas) Then
|
||||
System.IO.File.Delete(ArchivoCuentas)
|
||||
End If
|
||||
|
||||
Dim fs As FileStream = File.Create(ArchivoCuentas)
|
||||
Dim info As Byte() = New UTF8Encoding(True).GetBytes(Str.ToString)
|
||||
fs.Write(info, 0, info.Length)
|
||||
fs.Close()
|
||||
If System.IO.File.Exists(ArchivoCuentas) Then System.IO.File.Delete(ArchivoCuentas)
|
||||
|
||||
'DESCARGA XML
|
||||
Dim DescargaZIP As Ionic.Zip.ZipFile = New Ionic.Zip.ZipFile()
|
||||
|
||||
If IO.File.Exists(ArchivoCuentas) Then
|
||||
DescargaZIP.AddFile(ArchivoCuentas, "")
|
||||
End If
|
||||
'generar el sello
|
||||
SellarXML(Str.ToString, ArchivoCuentas, 1)
|
||||
|
||||
If IO.File.Exists(ArchivoCuentas) Then DescargaZIP.AddFile(ArchivoCuentas, "")
|
||||
|
||||
DescargaZIP.Save(Response.OutputStream)
|
||||
Response.AddHeader("content-Disposition", String.Format("attachment; filename={0}{1}{2}CT.zip", UsuarioActual.Empresa.RFC, DdlEjercicio.SelectedValue, DdlPeriodo.SelectedValue.PadLeft(2, "0"c)))
|
||||
@@ -172,6 +174,84 @@ Partial Class Contabilidad_ContabilidadElectronica
|
||||
|
||||
End Sub
|
||||
|
||||
Private Function SellarXML(xmltexto As String, ArchivoCuentas As String, Opcion As Integer) As String
|
||||
Dim ArchivoLLave As String = $"{UsuarioActual.Empresa.Ruta}Certificados\{UsuarioActual.Empresa.ArchivoKey}"
|
||||
Dim Archivopfx As String = $"{UsuarioActual.Empresa.Ruta}Certificados\{UsuarioActual.Empresa.FielPFX }"
|
||||
Dim Clavepfx As String = UsuarioActual.Empresa.FielPassword
|
||||
|
||||
Dim xsltPath As String
|
||||
Select Case Opcion
|
||||
Case 1
|
||||
xsltPath = $"{AppDomain.CurrentDomain.BaseDirectory}Temp\CatalogoCuentas_1_3.xslt"
|
||||
Case 2
|
||||
xsltPath = $"{AppDomain.CurrentDomain.BaseDirectory}Temp\BalanzaComprobacion_1_3.xslt"
|
||||
End Select
|
||||
|
||||
If Not File.Exists(ArchivoLLave) Then
|
||||
Alert("El archivo de llave privada no existe", TipoMensaje.MsgError)
|
||||
End If
|
||||
|
||||
' 1. Cargar y transformar el XML para obtener la Cadena Original
|
||||
Dim originalCadena As String = GenerarCadenaOriginal(xmltexto, xsltPath)
|
||||
|
||||
' 2. Cargar tu certificado PFX (incluye la clave privada)
|
||||
Dim cert As New X509Certificate2(Archivopfx, Clavepfx, X509KeyStorageFlags.MachineKeySet)
|
||||
|
||||
' 3. Firmar la cadena con SHA256
|
||||
Dim selloBytes As Byte()
|
||||
Using rsa As RSA = cert.GetRSAPrivateKey()
|
||||
selloBytes = rsa.SignData(
|
||||
Encoding.UTF8.GetBytes(originalCadena),
|
||||
HashAlgorithmName.SHA256,
|
||||
RSASignaturePadding.Pkcs1)
|
||||
End Using
|
||||
Dim selloBase64 As String = Convert.ToBase64String(selloBytes)
|
||||
|
||||
' 4. Obtener el certificado (público) en Base64 y el número de certificado
|
||||
Dim certBase64 As String = Convert.ToBase64String(cert.RawData)
|
||||
Dim noCertificado As String = cert.GetSerialNumberString()
|
||||
|
||||
' 5. Insertar atributos en el XML
|
||||
Dim xmlDoc As New XmlDocument()
|
||||
xmlDoc.PreserveWhitespace = True ' conserva espacios y saltos
|
||||
xmlDoc.LoadXml(xmltexto)
|
||||
|
||||
Dim root As XmlElement = xmlDoc.DocumentElement
|
||||
root.SetAttribute("Sello", selloBase64)
|
||||
root.SetAttribute("noCertificado", noCertificado)
|
||||
root.SetAttribute("certificado", certBase64)
|
||||
|
||||
' 6. Guardar archivo sellado
|
||||
Dim StrFinal As String = xmlDoc.OuterXml
|
||||
Dim fs As FileStream = File.Create(ArchivoCuentas)
|
||||
Dim info As Byte() = New UTF8Encoding(True).GetBytes(StrFinal)
|
||||
fs.Write(info, 0, info.Length)
|
||||
fs.Close()
|
||||
'xmlDoc.Save(ArchivoCuentas)
|
||||
Return StrFinal
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Aplica el XSLT para generar la Cadena Original según SAT.
|
||||
''' </summary>
|
||||
Function GenerarCadenaOriginal(xmlContenido As String, xsltFile As String) As String
|
||||
' Carga la transformación XSLT
|
||||
Dim xslt As New XslCompiledTransform()
|
||||
xslt.Load(xsltFile)
|
||||
|
||||
' Prepara un StringReader sobre el contenido del XML
|
||||
Using sr As New StringReader(xmlContenido),
|
||||
xr As XmlReader = XmlReader.Create(sr),
|
||||
sw As New StringWriter()
|
||||
|
||||
' Ejecuta la transformación
|
||||
xslt.Transform(xr, Nothing, sw)
|
||||
|
||||
' Devuelve la cadena original (trim para quitar saltos extra)
|
||||
Return sw.ToString().Trim()
|
||||
End Using
|
||||
End Function
|
||||
|
||||
Private Sub GeneraBalanza()
|
||||
Dim FechaI As Date = String.Format("01/{0}/{1}", DdlPeriodo.SelectedValue.PadLeft(2, "0"c), DdlEjercicio.SelectedValue).ToDate
|
||||
Dim FechaF As Date = FechaI.LastDayOfMonth
|
||||
@@ -186,10 +266,10 @@ Partial Class Contabilidad_ContabilidadElectronica
|
||||
If DtCuentas IsNot Nothing Then
|
||||
Dim Deudor As Decimal = DtCuentas.SUM("SaldoAD")
|
||||
Dim Acreedor As Decimal = DtCuentas.SUM("SaldoAA")
|
||||
If Deudor <> Acreedor Then
|
||||
Alert("los Saldos Actuales no cuadran.", TipoMensaje.MsgError)
|
||||
Exit Sub
|
||||
End If
|
||||
'If Deudor <> Acreedor Then
|
||||
' Alert("los Saldos Actuales no cuadran.", TipoMensaje.MsgError)
|
||||
' Exit Sub
|
||||
'End If
|
||||
End If
|
||||
Else
|
||||
Dim ObjConpaq As New ClsContPAQi(UsuarioActual.Empresa)
|
||||
@@ -204,24 +284,23 @@ Partial Class Contabilidad_ContabilidadElectronica
|
||||
|
||||
'CABECERA
|
||||
Str.Append("<?xml version=""1.0"" encoding=""UTF-8""?>")
|
||||
Str.Append("<BCE:Balanza xsi:schemaLocation=""www.sat.gob.mx/esquemas/ContabilidadE/1_3/BalanzaComprobacion/BalanzaComprobacion_1_3.xsd"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" Version=""1.3"" ")
|
||||
Str.Append("<bnc:Balanza ")
|
||||
Str.Append("xmlns:bnc =""http://www.sat.gob.mx/esquemas/ContabilidadE/1_3/BalanzaComprobacion"" ")
|
||||
Str.Append("xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" ")
|
||||
Str.Append("xsi:schemaLocation=""http://www.sat.gob.mx/esquemas/ContabilidadE/1_3/BalanzaComprobacion http://www.sat.gob.mx/esquemas/ContabilidadE/1_3/BalanzaComprobacion/BalanzaComprobacion_1_3.xsd"" ")
|
||||
Str.Append("Version=""1.3"" ")
|
||||
|
||||
Str.AppendFormat("RFC=""{0}"" ", UsuarioActual.Empresa.RFC)
|
||||
Str.AppendFormat("Mes=""{0}"" ", DdlPeriodo.SelectedValue)
|
||||
Str.AppendFormat("Anio=""{0}"" ", DdlEjercicio.SelectedValue)
|
||||
|
||||
Str.AppendFormat("TipoEnvio=""{0}"" ", "C")
|
||||
Str.AppendFormat("FechaModBal=""{0}"" ", FechaF.ToString("yyyy-MM-dd"))
|
||||
|
||||
Str.AppendFormat("Sello=""{0}"" ", "123")
|
||||
Str.AppendFormat("noCertificado=""{0}"" ", "123")
|
||||
Str.AppendFormat("Certificado=""{0}"" ", "1234567890")
|
||||
Str.Append("xmlns:BCE=""www.sat.gob.mx/esquemas/ContabilidadE/1_3/BalanzaComprobacion"">")
|
||||
|
||||
Str.AppendFormat("FechaModBal=""{0}"" >", FechaF.ToString("yyyy-MM-dd"))
|
||||
'DETALLES
|
||||
For Each Dr As DataRow In DtCuentas.Rows
|
||||
Str.Append("<BCE:Ctas ")
|
||||
Str.Append("<bnc:Ctas ")
|
||||
If UsuarioActual.Empresa.TipoContabilidad = 1 Then
|
||||
Str.AppendFormat("NumCta=""{0}"" ", Dr("Codigo").ToString)
|
||||
Str.AppendFormat("NumCta=""{0}"" ", Dr("Codigo").ToString.Replace("-", ""))
|
||||
Str.AppendFormat("SaldoIni=""{0}"" ", Dr("SaldoInicial").ToString)
|
||||
Str.AppendFormat("Debe=""{0}"" ", Dr("Cargos").ToString)
|
||||
Str.AppendFormat("Haber=""{0}"" ", Dr("Abonos").ToString)
|
||||
@@ -236,12 +315,10 @@ Partial Class Contabilidad_ContabilidadElectronica
|
||||
|
||||
Str.Append("/>")
|
||||
Next
|
||||
|
||||
DtCuentas.Dispose()
|
||||
|
||||
'FIN
|
||||
Str.Append("</BCE:Balanza>")
|
||||
|
||||
Str.Append("</bnc:Balanza>")
|
||||
'GUARDA ARHIVO
|
||||
ArchivoBalanza = Server.MapPath(String.Format("~/Empresas/{0}/ContabilidadElectronica/{1}{2}{3}BN.xml", UsuarioActual.CveEmpresa, UsuarioActual.Empresa.RFC, DdlEjercicio.SelectedValue, DdlPeriodo.SelectedValue.PadLeft(2, "0"c)))
|
||||
|
||||
@@ -251,14 +328,10 @@ Partial Class Contabilidad_ContabilidadElectronica
|
||||
|
||||
'SOBREESCRIBE
|
||||
If System.IO.File.Exists(ArchivoBalanza) Then System.IO.File.Delete(ArchivoBalanza)
|
||||
|
||||
Dim fs As FileStream = File.Create(ArchivoBalanza)
|
||||
Dim info As Byte() = New UTF8Encoding(True).GetBytes(Str.ToString)
|
||||
fs.Write(info, 0, info.Length)
|
||||
fs.Close()
|
||||
|
||||
'DESCARGA XML
|
||||
Dim DescargaZIP As Ionic.Zip.ZipFile = New Ionic.Zip.ZipFile()
|
||||
'generar el sello
|
||||
SellarXML(Str.ToString, ArchivoBalanza, 2)
|
||||
|
||||
If IO.File.Exists(ArchivoBalanza) Then
|
||||
DescargaZIP.AddFile(ArchivoBalanza, "")
|
||||
@@ -275,6 +348,4 @@ Partial Class Contabilidad_ContabilidadElectronica
|
||||
|
||||
#End Region
|
||||
|
||||
|
||||
|
||||
End Class
|
||||
|
||||
Reference in New Issue
Block a user