This commit is contained in:
2025-05-20 17:14:02 -07:00
parent d4a08c9d28
commit a3add6893c

View File

@@ -1,9 +1,20 @@
Option Explicit On Option Explicit On
Option Strict On Option Strict On
Imports System.Data
Imports System.IO
Imports Extensiones 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 Partial Class Contabilidad_ContabilidadElectronica
Inherits ClsPaginas Inherits ClsPaginas
@@ -95,7 +106,7 @@ Partial Class Contabilidad_ContabilidadElectronica
End If End If
objconta.Dispose() objconta.Dispose()
Else Else
Dim ObjConpaq As New ClsContPAQi(UsuarioActual.Empresa) Dim ObjConpaq As New ClsContPAQi(UsuarioActual.Empresa)
If ObjConpaq.GetCuentasElectronica(MinFecha, FechaF) Then If ObjConpaq.GetCuentasElectronica(MinFecha, FechaF) Then
DtCuentas = ObjConpaq.DtResultados DtCuentas = ObjConpaq.DtResultados
End If End If
@@ -112,9 +123,6 @@ Partial Class Contabilidad_ContabilidadElectronica
Str.AppendFormat("RFC=""{0}"" ", UsuarioActual.Empresa.RFC) Str.AppendFormat("RFC=""{0}"" ", UsuarioActual.Empresa.RFC)
Str.AppendFormat("Mes=""{0}"" ", DdlPeriodo.SelectedValue) Str.AppendFormat("Mes=""{0}"" ", DdlPeriodo.SelectedValue)
Str.AppendFormat("Anio=""{0}"" ", DdlEjercicio.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"">") Str.Append("xmlns:catalogocuentas=""www.sat.gob.mx/esquemas/ContabilidadE/1_3/CatalogoCuentas"">")
'DETALLES '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" ArchivoCuentas = $"{UsuarioActual.Empresa.Ruta}/ContabilidadElectronica/{ UsuarioActual.Empresa.RFC}{DdlEjercicio.SelectedValue}{DdlPeriodo.SelectedValue.PadLeft(2, "0"c)}CT.xml"
'SOBREESCRIBE 'SOBREESCRIBE
If System.IO.File.Exists(ArchivoCuentas) Then If System.IO.File.Exists(ArchivoCuentas) Then System.IO.File.Delete(ArchivoCuentas)
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()
'DESCARGA XML 'DESCARGA XML
Dim DescargaZIP As Ionic.Zip.ZipFile = New Ionic.Zip.ZipFile() Dim DescargaZIP As Ionic.Zip.ZipFile = New Ionic.Zip.ZipFile()
If IO.File.Exists(ArchivoCuentas) Then 'generar el sello
DescargaZIP.AddFile(ArchivoCuentas, "") SellarXML(Str.ToString, ArchivoCuentas, 1)
End If
If IO.File.Exists(ArchivoCuentas) Then DescargaZIP.AddFile(ArchivoCuentas, "")
DescargaZIP.Save(Response.OutputStream) 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))) 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 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() Private Sub GeneraBalanza()
Dim FechaI As Date = String.Format("01/{0}/{1}", DdlPeriodo.SelectedValue.PadLeft(2, "0"c), DdlEjercicio.SelectedValue).ToDate Dim FechaI As Date = String.Format("01/{0}/{1}", DdlPeriodo.SelectedValue.PadLeft(2, "0"c), DdlEjercicio.SelectedValue).ToDate
Dim FechaF As Date = FechaI.LastDayOfMonth Dim FechaF As Date = FechaI.LastDayOfMonth
@@ -186,10 +266,10 @@ Partial Class Contabilidad_ContabilidadElectronica
If DtCuentas IsNot Nothing Then If DtCuentas IsNot Nothing Then
Dim Deudor As Decimal = DtCuentas.SUM("SaldoAD") Dim Deudor As Decimal = DtCuentas.SUM("SaldoAD")
Dim Acreedor As Decimal = DtCuentas.SUM("SaldoAA") Dim Acreedor As Decimal = DtCuentas.SUM("SaldoAA")
If Deudor <> Acreedor Then 'If Deudor <> Acreedor Then
Alert("los Saldos Actuales no cuadran.", TipoMensaje.MsgError) ' Alert("los Saldos Actuales no cuadran.", TipoMensaje.MsgError)
Exit Sub ' Exit Sub
End If 'End If
End If End If
Else Else
Dim ObjConpaq As New ClsContPAQi(UsuarioActual.Empresa) Dim ObjConpaq As New ClsContPAQi(UsuarioActual.Empresa)
@@ -204,24 +284,23 @@ Partial Class Contabilidad_ContabilidadElectronica
'CABECERA 'CABECERA
Str.Append("<?xml version=""1.0"" encoding=""UTF-8""?>") 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("RFC=""{0}"" ", UsuarioActual.Empresa.RFC)
Str.AppendFormat("Mes=""{0}"" ", DdlPeriodo.SelectedValue) Str.AppendFormat("Mes=""{0}"" ", DdlPeriodo.SelectedValue)
Str.AppendFormat("Anio=""{0}"" ", DdlEjercicio.SelectedValue) Str.AppendFormat("Anio=""{0}"" ", DdlEjercicio.SelectedValue)
Str.AppendFormat("TipoEnvio=""{0}"" ", "C") Str.AppendFormat("TipoEnvio=""{0}"" ", "C")
Str.AppendFormat("FechaModBal=""{0}"" ", FechaF.ToString("yyyy-MM-dd")) 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"">")
'DETALLES 'DETALLES
For Each Dr As DataRow In DtCuentas.Rows For Each Dr As DataRow In DtCuentas.Rows
Str.Append("<BCE:Ctas ") Str.Append("<bnc:Ctas ")
If UsuarioActual.Empresa.TipoContabilidad = 1 Then 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("SaldoIni=""{0}"" ", Dr("SaldoInicial").ToString)
Str.AppendFormat("Debe=""{0}"" ", Dr("Cargos").ToString) Str.AppendFormat("Debe=""{0}"" ", Dr("Cargos").ToString)
Str.AppendFormat("Haber=""{0}"" ", Dr("Abonos").ToString) Str.AppendFormat("Haber=""{0}"" ", Dr("Abonos").ToString)
@@ -236,12 +315,10 @@ Partial Class Contabilidad_ContabilidadElectronica
Str.Append("/>") Str.Append("/>")
Next Next
DtCuentas.Dispose() DtCuentas.Dispose()
'FIN 'FIN
Str.Append("</BCE:Balanza>") Str.Append("</bnc:Balanza>")
'GUARDA ARHIVO '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))) 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 'SOBREESCRIBE
If System.IO.File.Exists(ArchivoBalanza) Then System.IO.File.Delete(ArchivoBalanza) 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 'DESCARGA XML
Dim DescargaZIP As Ionic.Zip.ZipFile = New Ionic.Zip.ZipFile() Dim DescargaZIP As Ionic.Zip.ZipFile = New Ionic.Zip.ZipFile()
'generar el sello
SellarXML(Str.ToString, ArchivoBalanza, 2)
If IO.File.Exists(ArchivoBalanza) Then If IO.File.Exists(ArchivoBalanza) Then
DescargaZIP.AddFile(ArchivoBalanza, "") DescargaZIP.AddFile(ArchivoBalanza, "")
@@ -275,6 +348,4 @@ Partial Class Contabilidad_ContabilidadElectronica
#End Region #End Region
End Class End Class