Beispiel #1
0
        public static string BuildQRCode(this string xml, string QRCodeTokenID, string QRCodeTokenCsc, DateTime?ContingencyDate)
        {
            AssertionConcern.AssertArgumentNotNullEmpty(xml, "XML obrigatório para gerar o QRCode");

            var xmlDocument = new XmlDocument();

            xmlDocument.LoadXml(xml);

            var ns = new XmlNamespaceManager(xmlDocument.NameTable);

            ns.AddNamespace("nfe", "http://www.portalfiscal.inf.br/nfe");
            ns.AddNamespace("sign", "http://www.w3.org/2000/09/xmldsig#");

            var model = xmlDocument.SelectSingleNode("//*[local-name()='mod']");

            //AssertionConcern.AssertArgumentNotNull(model, "Não foi possível encontrar o node \"mod\" no XML da NF para poder montar o QRCode");
            if (model?.InnerText != "65")
            {
                return(xml);
            }

            var tokenID  = QRCodeTokenID;
            var tokenCsc = QRCodeTokenCsc;

            AssertionConcern.AssertArgumentFalse((string.IsNullOrEmpty(tokenID) || string.IsNullOrEmpty(tokenCsc)), "QrCode Token e QrCode Token Csc são obrigatórios para NFCe");

            var qrcodeUrl = xmlDocument.SelectSingleNode("//*[local-name()='qrCode']");

            AssertionConcern.AssertArgumentNotNull(qrcodeUrl, "Não foi possível encontrar o node \"qrCode\" no XML da NF para poder montar o QRCode");

            AssertionConcern.AssertArgumentNotNull(xmlDocument.SelectSingleNode("//nfe:infNFe", ns), "Não foi possível encontrar o node \"infNFe\" no XML da NF para poder montar o QRCode");
            AssertionConcern.AssertArgumentNotNull(xmlDocument.SelectSingleNode("//nfe:tpAmb", ns), "Não foi possível encontrar o node \"tpAmb\" no XML da NF para poder montar o QRCode");
            AssertionConcern.AssertArgumentNotNull(xmlDocument.SelectSingleNode("//nfe:ide/nfe:dhEmi", ns), "Não foi possível encontrar o node \"dhEmi\" no XML da NF para poder montar o QRCode");
            AssertionConcern.AssertArgumentNotNull(xmlDocument.SelectSingleNode("//nfe:total/nfe:ICMSTot/nfe:vNF", ns), "Não foi possível encontrar o node \"vNF\" no XML da NF para poder montar o QRCode");
            AssertionConcern.AssertArgumentNotNull(xmlDocument.SelectSingleNode("//nfe:total/nfe:ICMSTot/nfe:vICMS", ns), "Não foi possível encontrar o node \"vICMS\" no XML da NF para poder montar o QRCode");
            AssertionConcern.AssertArgumentNotNull(xmlDocument.SelectSingleNode("//nfe:enviNFe/nfe:NFe/sign:Signature/sign:SignedInfo/sign:Reference/sign:DigestValue", ns), "Não foi possível encontrar o node \"DigestValue\" no XML da NF para poder montar o QRCode");

            var tpEmis = xmlDocument.SelectSingleNode("//nfe:tpEmis", ns).InnerText;

            //[44 exatos] - chNFe -- Chave de Acesso da NFCe
            //ex: NFe13140213998916000124650010000003461000003464
            var chNFe = xmlDocument.SelectSingleNode("//nfe:infNFe", ns).Attributes["Id"].InnerText.Substring(3); //Remove "NFe" do início

            //[3 exatos] nVersao -- Versão do QR Code -- Nessa versão informar "100"
            const string nVersao = "2";

            //[1 exato] tpAmb -- Identificação do Ambiente (1 – Produção, 2 –Homologação)
            var tpAmb = xmlDocument.SelectSingleNode("//nfe:tpAmb", ns).InnerText;

            //[11-20] cDest -- Documento de Identificação do Consumidor (CNPJ/CPF/ID Estrangeiro)
            var cDest = "";

            if (xmlDocument.SelectSingleNode("//nfe:dest/nfe:CNPJ", ns) != null)
            {
                cDest = xmlDocument.SelectSingleNode("//nfe:dest/nfe:CNPJ", ns).InnerText.PadLeft(14, '0');
            }
            else if (xmlDocument.SelectSingleNode("//nfe:dest/nfe:CPF", ns) != null)
            {
                cDest = xmlDocument.SelectSingleNode("//nfe:dest/nfe:CPF", ns).InnerText.PadLeft(11, '0');
            }
            else if (xmlDocument.SelectSingleNode("//nfe:dest/nfe:idEstrangeiro", ns) != null)
            {
                cDest = xmlDocument.SelectSingleNode("//nfe:dest/nfe:idEstrangeiro", ns).InnerText.PadLeft(11, '0');
            }
            //Identificação do cliente não é obrigatória para NFCe

            //[50 convertido para hex] dhEmi -- Data e Hora de Emissão da NFC-e
            DateTime dEmi;

            DateTime.TryParse(xmlDocument.SelectSingleNode("//nfe:ide/nfe:dhEmi", ns).InnerText, out dEmi);
            var dhEmi = dEmi.ToString("dd");

            //[15] vNF -- Valor Total da NFC-e
            var vNF = xmlDocument.SelectSingleNode("//nfe:total/nfe:ICMSTot/nfe:vNF", ns).InnerText;

            //[15] vICMS -- Valor Total ICMS na NFC-e
            var vICMS = xmlDocument.SelectSingleNode("//nfe:total/nfe:ICMSTot/nfe:vICMS", ns).InnerText;

            //[56 exatos convertido para hex] digVal -- Digest Value da NFC-e
            var digVal = xmlDocument.SelectSingleNode("//nfe:enviNFe/nfe:NFe/sign:Signature/sign:SignedInfo/sign:Reference/sign:DigestValue", ns).InnerText;

            digVal = digVal.ToHexString();

            var sb = new StringBuilder();

            int tokenIDSignificantNumber;

            if (!int.TryParse(tokenID, out tokenIDSignificantNumber))
            {
                throw new InvalidOperationException(string.Format("Código identificador do CSC é inválido. Devem ser informados apenas números. Valor: {0}", tokenID));
            }

            var qrCodeTemplate = string.Empty;

            if (ContingencyDate.HasValue)
            {
                qrCodeTemplate = "{0}|{1}|{2}|{3}|{4}|{5}|{6}";
            }
            else
            {
                qrCodeTemplate = "{0}|{1}|{2}|{6}";
            }

            sb.AppendFormat(qrCodeTemplate, chNFe, nVersao, tpAmb, dhEmi, vNF, digVal, tokenIDSignificantNumber);

            var hash = string.Concat(sb.ToString(), tokenCsc).GenerateHash();

            sb.AppendFormat("|{0}", hash);

            var qrCode = string.Format(qrcodeUrl.InnerText.IndexOf('?') > -1 ? "{0}&p={1}" : "{0}?p={1}", qrcodeUrl.InnerText, sb);

            xmlDocument.SelectSingleNode("//*[local-name()='qrCode']").InnerText = "{QRCODE}";
            xmlDocument.InnerXml = xmlDocument.OuterXml.Replace("{QRCODE}", string.Format("<![CDATA[{0}]]>", qrCode));

            return(xmlDocument.OuterXml);
        }