예제 #1
0
        public XmlDocument GeneraFacturaXml(string certificado, string llave,
                                            bool incluirDetallista, bool incluirAddenda, bool incluirAlsuper,
                                            bool incluirEdifact, bool incluirComercExt, bool incluirPago, bool incluirAmazon, out string cadenaOriginal, out string sello)
        {
            int cantComplementos = 0;

            // tipoComplemento: detallista, addenda, alsuper
            string tipoComplemento = string.Empty;

            // Generamos el comprobante y agregamos el certificado
            GeneraComprobante();
            _comprobante.Certificado = certificado;

            #region Agregamos el nodo detallista
            if (incluirDetallista)
            {
                tipoComplemento = "detallista";

                ComplementoFE complemento  = new ComplementoFE(_iniAdd);
                XmlDocument   tempDocument = complemento.GeneraComplementoXml(tipoComplemento);

                _comprobante.Complemento    = new Schemasv33modif.ComprobanteComplemento[1];
                _comprobante.Complemento[0] = new Schemasv33modif.ComprobanteComplemento
                {
                    Any = new[] { tempDocument["detallista:detallista"] }
                };
                cantComplementos += 1;
            }
            #endregion

            #region Agrega Complemento Comercio Exterior
            if (incluirComercExt)
            {
                tipoComplemento = "comercExterior";

                ComplementoFE complemento  = new ComplementoFE(_iniAdd);
                XmlDocument   tempDocument = complemento.GeneraComplementoXml(tipoComplemento);

                _comprobante.Complemento    = new Schemasv33modif.ComprobanteComplemento[1];
                _comprobante.Complemento[0] = new Schemasv33modif.ComprobanteComplemento
                {
                    Any = new[] { tempDocument["cce11:ComercioExterior"] }
                };
                cantComplementos += 1;
            }

            #endregion

            #region Agrega Complemento de Pago
            if (incluirPago)
            {
                tipoComplemento = "pago";

                ComplementoFE complemento  = new ComplementoFE(_iniAdd);
                XmlDocument   tempDocument = complemento.GeneraComplementoXml(tipoComplemento);

                _comprobante.Complemento    = new Schemasv33modif.ComprobanteComplemento[1];
                _comprobante.Complemento[0] = new Schemasv33modif.ComprobanteComplemento
                {
                    Any = new[] { tempDocument["pago10:Pagos"] }
                };
                cantComplementos += 1;
            }
            #endregion

            #region Generamos un documento XML usando la información actual de comprobante, detallista, ComercExt y Pago
            XmlDocument doc = new XmlDocument();
            using (MemoryStream tempStream = new MemoryStream())
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Schemasv33modif.Comprobante));

                serializer.Serialize(tempStream, _comprobante);
                tempStream.Seek(0, SeekOrigin.Begin);
                doc.Load(tempStream);
            }
            #endregion

            #region Generamos la cadena original
            using (MemoryStream tempStream = new MemoryStream())
            {
                using (
                    XmlTextWriter xmlWriter = new XmlTextWriter(tempStream, Encoding.UTF8))
                {
                    doc.WriteContentTo(xmlWriter);
                    xmlWriter.Flush();
                    tempStream.Seek(0, SeekOrigin.Begin);
                    XPathDocument xpathFactura = new XPathDocument(tempStream);
                    xmlWriter.Close();

                    // Generamos la cadena original usando el archivo XSLT del SAT Ver33
                    XslCompiledTransform xslCadena = new XslCompiledTransform();
                    xslCadena.Load("cadenaoriginal_3_3_local.xslt");

                    using (MemoryStream cadenaStream = new MemoryStream())
                    {
                        xslCadena.Transform(xpathFactura, null, cadenaStream);
                        cadenaOriginal = cadenaStream.GetString();
                    }
                }
            }

            // Elimina saltos de linea y espacios en blanco entre los campos de la cadena original
            char[]   crlf         = new char[] { '\n', '\r' };
            string[] cadenaLineas = cadenaOriginal.Split(crlf);
            cadenaOriginal = null;
            for (int i = 0; i < cadenaLineas.Length; i++)
            {
                if ((cadenaLineas[i].Length >= 2) || (cadenaLineas[i].StartsWith("-")))
                {
                    cadenaOriginal += cadenaLineas[i].Substring(2).Trim();
                }
            }

            #endregion

            #region Generamos el sello de la factura
            // La encriptación de la versión 33 debe ser en SHA-256
            RSACryptoServiceProvider provider = OpenSSL.GetRsaProviderFromPem(llave);
            if (provider == null)
            {
                throw new Exception(
                          "No se pudo crear el proveedor de seguridad a partir del archivo fel");
            }
            byte[] selloBytes = provider.SignData(
                Encoding.UTF8.GetBytes(cadenaOriginal), "SHA256");
            sello = Convert.ToBase64String(selloBytes);

            // Actualizamos el documento original con el sello
            _comprobante.Sello = sello;

            #endregion

            #region Agregamos la addenda
            if (incluirAddenda)
            {
                tipoComplemento = "addenda";

                ComplementoFE complemento  = new ComplementoFE(_iniAdd);
                XmlDocument   tempDocument = complemento.GeneraComplementoXml(tipoComplemento, cadenaOriginal);

                _comprobante.Addenda = new Schemasv33modif.ComprobanteAddenda
                {
                    Any = new[] { tempDocument["Addenda"]["requestForPayment"] }
                };
            }
            #endregion

            #region Agrega addenda Alsuper
            if (incluirAlsuper)
            {
                tipoComplemento = "alsuper";

                ComplementoFE complemento  = new ComplementoFE(_iniAdd);
                XmlDocument   tempDocument = complemento.GeneraComplementoXml(tipoComplemento);

                _comprobante.Addenda = new Schemasv33modif.ComprobanteAddenda
                {
                    Any = new[]
                    {
                        tempDocument["alsuper:Alsuper"]
                    }
                };
            }
            #endregion

            #region Agrega addenda EDIFACT
            if (incluirEdifact)
            {
                tipoComplemento = "edifact";
                ComplementoFE complemento  = new ComplementoFE(_iniAdd);
                XmlDocument   tempDocument = complemento.GeneraComplementoXml(tipoComplemento, cadenaOriginal, sello);

                _comprobante.Addenda = new Schemasv33modif.ComprobanteAddenda
                {
                    Any = new[]
                    {
                        tempDocument["lev1add:EDCINVOICE"]
                    }
                };
            }
            #endregion

            #region Agrega addenda Amazon
            if (incluirAmazon)
            {
                tipoComplemento = "amazon";
                ComplementoFE complemento  = new ComplementoFE(_iniAdd);
                XmlDocument   tempDocument = complemento.GeneraComplementoXml(tipoComplemento, cadenaOriginal, sello);

                _comprobante.Addenda = new Schemasv33modif.ComprobanteAddenda
                {
                    Any = new[]
                    {
                        tempDocument["amazon:ElementosAmazon"]
                    }
                };
            }
            #endregion

            #region  Genera documento final
            using (MemoryStream tempStream = new MemoryStream())
            {
                doc = new XmlDocument();
                XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
                namespaces.Add("cfdi", "http://www.sat.gob.mx/cfd/3");
                XmlSerializer serializer = new XmlSerializer(typeof(Schemasv33modif.Comprobante));

                serializer.Serialize(tempStream, _comprobante, namespaces);
                tempStream.Seek(0, SeekOrigin.Begin);
                doc.Load(tempStream);
            }

            #endregion

            #region Agregar atributos finales al documento
            XmlAttribute xsiAttrib     = doc.CreateAttribute("xsi:schemaLocation", "http://www.w3.org/2001/XMLSchema-instance");
            string       textoAtributo = "http://www.sat.gob.mx/cfd/3 " +
                                         "http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd " +
                                         "http://www.sat.gob.mx/detallista " +
                                         "http://www.sat.gob.mx/sitio_internet/cfd/detallista/detallista.xsd";
            if (incluirAlsuper)
            {
                textoAtributo = textoAtributo + " http://proveedores.alsuper.com/CFD " +
                                "http://proveedores.alsuper.com/addenda/1.xsd";
            }
            if (incluirComercExt)
            {
                textoAtributo = textoAtributo + " http://www.sat.gob.mx/ComercioExterior11 " +
                                "http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior11/ComercioExterior11.xsd";
            }
            if (incluirPago)
            {
                textoAtributo = textoAtributo + " http://www.sat.gob.mx/Pagos " +
                                "http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos10.xsd";
            }

            xsiAttrib.InnerText = textoAtributo;
            doc["cfdi:Comprobante"].Attributes.Append(xsiAttrib);
            #endregion

            return(doc);
        }
예제 #2
0
        public XmlDocument GeneraFacturaXml(string certificado, string llave,
                                            bool incluirDetallista, bool incluirAddenda, bool incluirAlsuper,
                                            bool incluirEdifact, out string cadenaOriginal, out string sello)
        {
            // tipoComplemento: detallista, addenda, alsuper
            string tipoComplemento = string.Empty;

            // Generamos el comprobante y agregamos el certificado
            GeneraComprobante();
            _comprobante.certificado = certificado;

            #region Agregamos el nodo detallista

            if (incluirDetallista)
            {
                tipoComplemento = "detallista";

                ComplementoFE complemento  = new ComplementoFE(_iniAdd);
                XmlDocument   tempDocument = complemento.GeneraComplementoXml(tipoComplemento);

                _comprobante.Complemento = new Schemasv22.ComprobanteComplemento
                {
                    Any = new[] { tempDocument["detallista:detallista"] }
                };
            }

            #endregion

            #region Generamos un documento XML usando la información actual de comprobante y detallista

            XmlDocument doc = new XmlDocument();
            using (MemoryStream tempStream = new MemoryStream())
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Schemasv22.Comprobante));
                serializer.Serialize(tempStream, _comprobante);
                tempStream.Seek(0, SeekOrigin.Begin);
                doc.Load(tempStream);
            }

            #endregion

            #region Generamos la cadena original

            using (MemoryStream tempStream = new MemoryStream())
            {
                using (
                    XmlTextWriter xmlWriter = new XmlTextWriter(tempStream, Encoding.UTF8))
                {
                    doc.WriteContentTo(xmlWriter);
                    xmlWriter.Flush();
                    tempStream.Seek(0, SeekOrigin.Begin);
                    XPathDocument xpathFactura = new XPathDocument(tempStream);
                    xmlWriter.Close();

                    // Generamos la cadena original usando el archivo XSLT del SAT Ver22
                    XslCompiledTransform xslCadena = new XslCompiledTransform();
                    xslCadena.Load("cadenaoriginal22.xslt");

                    using (MemoryStream cadenaStream = new MemoryStream())
                    {
                        xslCadena.Transform(xpathFactura, null, cadenaStream);
                        cadenaOriginal = cadenaStream.GetString();
                    }
                }
            }

            // Elimina saltos de linea y espacios en blanco entre los campos de la cadena original
            char[]   crlf         = new char[] { '\n', '\r' };
            string[] cadenaLineas = cadenaOriginal.Split(crlf);
            cadenaOriginal = null;
            for (int i = 0; i < cadenaLineas.Length; i++)
            {
                if ((cadenaLineas[i].Length >= 2) || (cadenaLineas[i].StartsWith("-")))
                {
                    cadenaOriginal += cadenaLineas[i].Substring(2).Trim();
                }
            }

            #endregion

            #region Generamos el sello de la factura

            RSACryptoServiceProvider provider = OpenSSL.GetRsaProviderFromPem(llave);
            if (provider == null)
            {
                throw new Exception(
                          "No se pudo crear el proveedor de seguridad a partir del archivo fel");
            }

            // Si la fecha es menor al 1 de Enero 2011, codifica con MD5 sino codifica con SHA1
            byte[] selloBytes;
            if (DateTime.Now < Convert.ToDateTime("2011-01-01"))
            {
                selloBytes = provider.SignData(
                    Encoding.UTF8.GetBytes(cadenaOriginal), "MD5");
            }
            else
            {
                selloBytes = provider.SignData(
                    Encoding.UTF8.GetBytes(cadenaOriginal), "SHA1");
            }

            sello = Convert.ToBase64String(selloBytes);

            // Actualizamos el documento original con el sello
            _comprobante.sello = sello;

            #endregion

            #region Agregamos la addenda

            if (incluirAddenda)
            {
                tipoComplemento = "addenda";

                ComplementoFE complemento  = new ComplementoFE(_iniAdd);
                XmlDocument   tempDocument = complemento.GeneraComplementoXml(tipoComplemento, cadenaOriginal);

                _comprobante.Addenda = new Schemasv22.ComprobanteAddenda
                {
                    Any = new[]
                    {
                        tempDocument["Addenda"]["requestForPayment"]
                    }
                };
            }

            #endregion

            #region Agrega addenda Alsuper
            if (incluirAlsuper)
            {
                tipoComplemento = "alsuper";

                ComplementoFE complemento  = new ComplementoFE(_iniAdd);
                XmlDocument   tempDocument = complemento.GeneraComplementoXml(tipoComplemento);

                _comprobante.Addenda = new Schemasv22.ComprobanteAddenda
                {
                    Any = new[]
                    {
                        tempDocument["alsuper:Alsuper"]
                    }
                };
            }
            #endregion

            #region Agrega addenda EDIFACT
            if (incluirEdifact)
            {
                tipoComplemento = "edifact";
                ComplementoFE complemento  = new ComplementoFE(_iniAdd);
                XmlDocument   tempDocument = complemento.GeneraComplementoXml(tipoComplemento);

                _comprobante.Addenda = new Schemasv22.ComprobanteAddenda
                {
                    Any = new[]
                    {
                        tempDocument["Addenda"]["Documento"]
                    }
                };
            }
            #endregion

            #region Generamos el documento final
            using (MemoryStream tempStream = new MemoryStream())
            {
                doc = new XmlDocument();
                XmlSerializer serializer = new XmlSerializer(typeof(Schemasv22.Comprobante));
                serializer.Serialize(tempStream, _comprobante);
                tempStream.Seek(0, SeekOrigin.Begin);
                doc.Load(tempStream);
            }
            #endregion

            #region Agregamos otros atributos del documento
            XmlAttribute xsiAttrib     = doc.CreateAttribute("xsi:schemaLocation", "http://www.w3.org/2001/XMLSchema-instance");
            string       textoAtributo = "http://www.sat.gob.mx/cfd/2 " +
                                         "http://www.sat.gob.mx/sitio_internet/cfd/2/cfdv22.xsd " +
                                         "http://www.sat.gob.mx/detallista " +
                                         "http://www.sat.gob.mx/sitio_internet/cfd/detallista/detallista.xsd";
            if (incluirAlsuper)
            {
                textoAtributo = textoAtributo + " http://proveedores.alsuper.com/CFD " +
                                "http://proveedores.alsuper.com/addenda/1.xsd";
            }
            xsiAttrib.InnerText = textoAtributo;
            doc["Comprobante"].Attributes.Append(xsiAttrib);
            #endregion

            return(doc);
        }