public MensagemRetornoEventoCancelamento CancelarNotaFiscal(string ufEmitente,
                                                                    CodigoUfIbge codigoUf, Ambiente ambiente, string cnpjEmitente, string chaveNFe,
                                                                    string protocoloAutorizacao, Modelo modeloNota, string justificativa)
        {
            var resultadoCancelamento = _nfeCancelamento.CancelarNotaFiscal(ufEmitente, codigoUf, ambiente,
                                                                            cnpjEmitente,
                                                                            chaveNFe,
                                                                            protocoloAutorizacao, modeloNota, justificativa);

            if (resultadoCancelamento.Status != StatusEvento.SUCESSO)
            {
                return(resultadoCancelamento);
            }

            var notaFiscalEntity = _notaFiscalRepository.GetNotaFiscalByChave(chaveNFe);

            _eventoService.Salvar(new EventoEntity
            {
                DataEvento = DateTime.ParseExact(resultadoCancelamento.DataEvento, "yyyy-MM-ddTHH:mm:sszzz",
                                                 CultureInfo.InvariantCulture),
                TipoEvento            = resultadoCancelamento.TipoEvento,
                Xml                   = resultadoCancelamento.Xml,
                NotaId                = notaFiscalEntity.Id,
                ChaveIdEvento         = resultadoCancelamento.IdEvento.Replace("ID", string.Empty),
                MotivoCancelamento    = resultadoCancelamento.MotivoCancelamento,
                ProtocoloCancelamento = resultadoCancelamento.ProtocoloCancelamento
            });

            notaFiscalEntity.Status = (int)Status.CANCELADA;
            _notaFiscalRepository.Salvar(notaFiscalEntity, null);

            return(resultadoCancelamento);
        }
        private Task <NotaFiscalEntity> ConsultarNotasAsync(int idNotaFiscalDb, string codigoUf,
                                                            X509Certificate2 certificado, ConfiguracaoEntity config)
        {
            return(Task.Run(async() =>
            {
                var notaFiscalDb = _notaFiscalRepository.GetNotaFiscalById(idNotaFiscalDb, true);
                var document = new XmlDocument();
                var ambiente = config.IsProducao ? Ambiente.Producao : Ambiente.Homologacao;
                var modelo = notaFiscalDb.Modelo.Equals("65") ? Modelo.Modelo65 : Modelo.Modelo55;

                var mensagemRetorno =
                    _nfeConsulta.ConsultarNotaFiscal(notaFiscalDb.Chave, codigoUf, certificado, ambiente, modelo);

                if (!mensagemRetorno.IsEnviada)
                {
                    return null;
                }

                mensagemRetorno.Protocolo.infProt.Id = null;
                var protSerialized = XmlUtil.Serialize(mensagemRetorno.Protocolo, "");

                var doc = XDocument.Parse(protSerialized);
                doc.Descendants().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();

                foreach (var element in doc.Descendants())
                {
                    element.Name = element.Name.LocalName;
                }

                using (var xmlReader = doc.CreateReader())
                {
                    document.Load(xmlReader);
                }

                notaFiscalDb.DataAutorizacao = mensagemRetorno.Protocolo.infProt.dhRecbto;
                notaFiscalDb.Protocolo = mensagemRetorno.Protocolo.infProt.nProt;

                var xml = await notaFiscalDb.LoadXmlAsync();
                xml = xml.Replace("<protNFe />", document.OuterXml.Replace("TProtNFe", "protNFe"));

                notaFiscalDb.Status = (int)Status.ENVIADA;
                _notaFiscalRepository.Salvar(notaFiscalDb, xml);

                return notaFiscalDb;
            }));
        }
        public int?Salvar(NotaFiscal notaFiscal)
        {
            var retorno = (int?)null;

            if (!notaFiscal.EhValido)
            {
                NotificarValidacoesErro(notaFiscal.ValidationResult);
                return(retorno);
            }

            if (!HasNotifications())
            {
                retorno = _notaFiscalRepository.Salvar(notaFiscal);

                if (!retorno.HasValue)
                {
                    NotificarValidacao(errorMessage: "Erro ao persistir Nota Fiscal!");
                }
            }

            return(retorno);
        }
        public void GerarNotaFiscal(Domain.Pedido pedido)
        {
            NotaFiscal notaFiscal = new NotaFiscal();

            notaFiscal.EmitirNotaFiscal(pedido);

            var gerouXML = _notaFiscalRepository.GerarArquivoXML(notaFiscal);

            if (gerouXML)
            {
                var notaFiscalId = _notaFiscalRepository.Salvar(notaFiscal);

                if (notaFiscalId > 0)
                {
                    foreach (var item in notaFiscal.ItensDaNotaFiscal)
                    {
                        item.IdNotaFiscal = notaFiscalId;
                        _notaFiscalItemRepository.Salvar(item);
                    }
                }
            }
        }
        private async Task ImportarXmlNotasFiscais(string path)
        {
            var regex = new Regex(@"[0-9]{44}-nf[c|e][e]?");

            var files = Directory.EnumerateFiles(path, "*.xml").Where(f => regex.IsMatch(f));

            await Task.Run(() =>
            {
                foreach (var file in files)
                {
                    try
                    {
                        var xml = File.ReadAllText(file);

                        var notaFiscal = _notaFiscalRepository.GetNotaFiscalFromNfeProcXml(xml);

                        var notaFiscalDb = _notaFiscalRepository.GetNotaFiscalByChave(notaFiscal.Identificacao.Chave);

                        if (notaFiscalDb != null)
                        {
                            return;
                        }

                        var notaFiscalEntity = new NotaFiscalEntity();

                        if (notaFiscal.Destinatario != null && notaFiscal.Destinatario.Endereco != null)
                        {
                            notaFiscalEntity.UfDestinatario = notaFiscal.Destinatario.Endereco.UF;
                        }
                        else
                        {
                            notaFiscalEntity.UfDestinatario = notaFiscal.Emitente.Endereco.UF;
                        }

                        notaFiscalEntity.Destinatario = notaFiscal.Destinatario == null
                            ? "CONSUMIDOR NÃO IDENTIFICADO"
                            : notaFiscal.Destinatario.NomeRazao;
                        notaFiscalEntity.DocumentoDestinatario = notaFiscal.Destinatario == null
                            ? null
                            : notaFiscal.Destinatario.Documento;
                        notaFiscalEntity.Status          = (int)notaFiscal.Identificacao.Status;
                        notaFiscalEntity.Chave           = notaFiscal.Identificacao.Chave;
                        notaFiscalEntity.DataEmissao     = notaFiscal.Identificacao.DataHoraEmissao;
                        notaFiscalEntity.Modelo          = notaFiscal.Identificacao.Modelo == Modelo.Modelo55 ? "55" : "65";
                        notaFiscalEntity.Serie           = notaFiscal.Identificacao.Serie.ToString();
                        notaFiscalEntity.TipoEmissao     = notaFiscal.Identificacao.TipoEmissao.ToString();
                        notaFiscalEntity.ValorDesconto   = notaFiscal.TotalNFe.IcmsTotal.ValorTotalDesconto;
                        notaFiscalEntity.ValorDespesas   = notaFiscal.TotalNFe.IcmsTotal.ValorDespesasAcessorias;
                        notaFiscalEntity.ValorFrete      = notaFiscal.TotalNFe.IcmsTotal.ValorTotalFrete;
                        notaFiscalEntity.ValorICMS       = notaFiscal.TotalNFe.IcmsTotal.ValorTotalIcms;
                        notaFiscalEntity.ValorProdutos   = notaFiscal.ValorTotalProdutos;
                        notaFiscalEntity.ValorSeguro     = notaFiscal.TotalNFe.IcmsTotal.ValorTotalSeguro;
                        notaFiscalEntity.ValorTotal      = notaFiscal.TotalNFe.IcmsTotal.ValorTotalNFe;
                        notaFiscalEntity.Ambiente        = notaFiscal.Identificacao.Ambiente == Ambiente.Homologacao ? 2 : 1;
                        notaFiscalEntity.Numero          = notaFiscal.Identificacao.Numero;
                        notaFiscalEntity.IsProducao      = notaFiscal.Identificacao.Ambiente == Ambiente.Producao;
                        notaFiscalEntity.DataAutorizacao = DateTime.ParseExact(notaFiscal.DhAutorizacao,
                                                                               "yyyy-MM-ddTHH:mm:sszzz", CultureInfo.InvariantCulture);
                        notaFiscalEntity.Protocolo = notaFiscal.ProtocoloAutorizacao;
                        notaFiscalEntity.XmlPath   = GetFullPath(file);

                        _notaFiscalRepository.Salvar(notaFiscalEntity, xml);
                    }
                    catch (Exception e)
                    {
                        log.Error(e);
                    }
                }
            });
        }
        public int EmitirNotaContingencia(NotaFiscal notaFiscal, string cscId, string csc)
        {
            var qrCode = string.Empty;
            string newNodeXml;
            const string nFeNamespaceName = "http://www.portalfiscal.inf.br/nfe";
            var digVal = string.Empty;

            var config = _configuracaoService.GetConfiguracao();

            notaFiscal.Identificacao.Numero = _configuracaoService.ObterProximoNumeroNotaFiscal(notaFiscal.Identificacao.Modelo);
            notaFiscal.Identificacao.DataHoraEntradaContigencia = config.DataHoraEntradaContingencia;
            notaFiscal.Identificacao.JustificativaContigencia = config.JustificativaContingencia;
            notaFiscal.Identificacao.TipoEmissao = notaFiscal.Identificacao.Modelo == Modelo.Modelo65
                ? TipoEmissao.ContigenciaNfce
                : TipoEmissao.FsDa;
            notaFiscal.CalcularChave();

            X509Certificate2 certificado;

            var certificadoEntity = _certificadoRepository.GetCertificado();

            if (!string.IsNullOrWhiteSpace(certificadoEntity.Caminho))
                certificado = _certificateManager.GetCertificateByPath(certificadoEntity.Caminho,
                    RijndaelManagedEncryption.DecryptRijndael(certificadoEntity.Senha));
            else
                certificado = _certificateManager.GetCertificateBySerialNumber(certificadoEntity.NumeroSerial, false);

            if (notaFiscal.Identificacao.Ambiente == Ambiente.Homologacao)
                notaFiscal.Produtos[0].Descricao = "NOTA FISCAL EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL";

            var refUri = "#NFe" + notaFiscal.Identificacao.Chave;

            var xml = Regex.Replace(XmlUtil.GerarXmlLoteNFe(notaFiscal, nFeNamespaceName), "<motDesICMS>1</motDesICMS>",
                string.Empty);
            XmlNode node = AssinaturaDigital.AssinarLoteComUmaNota(xml, refUri, certificado, ref digVal);

            if (notaFiscal.Identificacao.Modelo == Modelo.Modelo65)
            {
                qrCode = QrCodeUtil.GerarQrCodeNFe(notaFiscal.Identificacao.Chave, notaFiscal.Destinatario,
                    digVal, notaFiscal.Identificacao.Ambiente,
                    notaFiscal.Identificacao.DataHoraEmissao,
                    notaFiscal.TotalNFe.IcmsTotal.ValorTotalNFe.ToString("F", CultureInfo.InvariantCulture),
                    notaFiscal.TotalNFe.IcmsTotal.ValorTotalIcms.ToString("F", CultureInfo.InvariantCulture), cscId,
                    csc, notaFiscal.Identificacao.TipoEmissao);

                newNodeXml = node.InnerXml.Replace("<qrCode />", "<qrCode>" + qrCode + "</qrCode>");
            }
            else
            {
                newNodeXml = node.InnerXml.Replace("<infNFeSupl><qrCode /></infNFeSupl>", "");
            }

            var document = new XmlDocument();
            document.LoadXml(newNodeXml);
            node = document.DocumentElement;

            if (node == null) throw new ArgumentException("Xml inválido.");

            var lote = (TEnviNFe)XmlUtil.Deserialize<TEnviNFe>(node.OuterXml);
            var nfe = lote.NFe[0];

            //salvar nota PreEnvio aqui
            notaFiscal.Identificacao.Status = Status.CONTINGENCIA;

            var idNotaCopiaSeguranca =  _notaFiscalRepository.SalvarNotaFiscalPendente(notaFiscal,
                XmlUtil.GerarNfeProcXml(nfe, qrCode),
                notaFiscal.Identificacao.Ambiente);

            var notaFiscalEntity =  _notaFiscalRepository.GetNotaFiscalById(idNotaCopiaSeguranca, false);
            notaFiscalEntity.Status = (int)Status.CONTINGENCIA;
            var nfeProcXml = XmlUtil.GerarNfeProcXml(nfe, qrCode);

             _notaFiscalRepository.Salvar(notaFiscalEntity, nfeProcXml);
            notaFiscal.QrCodeUrl = qrCode;
            return idNotaCopiaSeguranca;
        }
        public void Salvar()
        {
            var id = _notaFiscalRepository.Salvar(notaFiscal);

            Assert.AreNotEqual(0, id, "Criação de um novo registro retorna ID diferente de zero.");
        }
        public int EnviarNotaFiscal(NotaFiscal notaFiscal, string cscId, string csc)
        {
            if (notaFiscal.Identificacao.Ambiente == Ambiente.Homologacao)
            {
                notaFiscal.Produtos[0].Descricao = "NOTA FISCAL EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL";
            }

            X509Certificate2 certificado;

            var certificadoEntity = _certificadoRepository.GetCertificado();

            if (!string.IsNullOrWhiteSpace(certificadoEntity.Caminho))
            {
                certificado = _certificateManager.GetCertificateByPath(certificadoEntity.Caminho,
                                                                       RijndaelManagedEncryption.DecryptRijndael(certificadoEntity.Senha));
            }
            else
            {
                certificado = _certificateManager.GetCertificateBySerialNumber(certificadoEntity.NumeroSerial, false);
            }

            if (!IsNotaFiscalValida(notaFiscal, cscId, csc, certificado))
            {
                throw new ArgumentException("Nota fiscal inválida.");
            }

            try
            {
                var              qrCode               = "";
                TNFe             nfe                  = null;
                var              newNodeXml           = string.Empty;
                var              idNotaCopiaSeguranca = 0;
                NotaFiscalEntity notaFiscalEntity     = null;

                var refUri           = "#NFe" + notaFiscal.Identificacao.Chave;
                var digVal           = "";
                var nFeNamespaceName = "http://www.portalfiscal.inf.br/nfe";

                var xml = Regex.Replace(XmlUtil.GerarXmlLoteNFe(notaFiscal, nFeNamespaceName),
                                        "<motDesICMS>1</motDesICMS>", string.Empty);
                XmlNode node = AssinaturaDigital.AssinarLoteComUmaNota(xml, refUri, certificado, ref digVal);

                try
                {
                    var codigoUf = (CodigoUfIbge)Enum.Parse(typeof(CodigoUfIbge), notaFiscal.Emitente.Endereco.UF);

                    newNodeXml = PreencherQrCode(notaFiscal, cscId, csc, ref qrCode, digVal, node);

                    var document = new XmlDocument();
                    document.LoadXml(newNodeXml);
                    node = document.DocumentElement;

                    var lote = (TEnviNFe)XmlUtil.Deserialize <TEnviNFe>(node.OuterXml);
                    nfe = lote.NFe[0];

                    var configuração = _configuracaoRepository.GetConfiguracao();

                    if (configuração.IsContingencia)
                    {
                        return(_emiteNotaFiscalContingenciaService.EmitirNotaContingencia(notaFiscal, cscId, csc));
                    }

                    NFeAutorizacao4Soap client = CriarClientWS(notaFiscal, certificado, codigoUf);
                    idNotaCopiaSeguranca = SalvarNotaFiscalPréEnvio(notaFiscal, qrCode, nfe);
                    TProtNFe protocolo = RetornarProtocoloParaLoteSomenteComUmaNotaFiscal(node, client);

                    if (protocolo.infProt.cStat.Equals("100"))
                    {
                        notaFiscalEntity =
                            _notaFiscalRepository.GetNotaFiscalById(idNotaCopiaSeguranca, false);
                        notaFiscalEntity.Status          = (int)Status.ENVIADA;
                        notaFiscalEntity.DataAutorizacao = DateTime.ParseExact(protocolo.infProt.dhRecbto,
                                                                               "yyyy-MM-ddTHH:mm:sszzz", CultureInfo.InvariantCulture);

                        notaFiscalEntity.Protocolo = protocolo.infProt.nProt;
                        var xmlNFeProc = XmlUtil.GerarNfeProcXml(nfe, qrCode, protocolo);
                        _notaFiscalRepository.Salvar(notaFiscalEntity, xmlNFeProc);
                    }
                    else
                    {
                        if (protocolo.infProt.xMotivo.Contains("Duplicidade"))
                        {
                            notaFiscalEntity = CorrigirNotaDuplicada(notaFiscal, qrCode, nFeNamespaceName,
                                                                     certificado, nfe, idNotaCopiaSeguranca);
                        }
                        else
                        {
                            //Nota continua com status pendente nesse caso
                            XmlUtil.SalvarXmlNFeComErro(notaFiscal, node);
                            var mensagem =
                                string.Concat(
                                    "O xml informado é inválido de acordo com o validar da SEFAZ. Nota Fiscal não enviada!",
                                    "\n", protocolo.infProt.xMotivo);
                            throw new ArgumentException(mensagem);
                        }
                    }

                    AtribuirValoresApósEnvioComSucesso(notaFiscal, qrCode, notaFiscalEntity);
                    return(idNotaCopiaSeguranca);
                }
                catch (Exception e)
                {
                    log.Error(e);
                    if (e is WebException || e.InnerException is WebException)
                    {
                        throw new Exception("Serviço indisponível ou sem conexão com a internet.",
                                            e.InnerException);
                    }

                    try
                    {
                        notaFiscalEntity = VerificarSeNotaFoiEnviada(notaFiscal, qrCode, nfe,
                                                                     idNotaCopiaSeguranca, notaFiscalEntity, nFeNamespaceName, certificado);
                    }
                    catch (Exception retornoConsultaException)
                    {
                        log.Error(retornoConsultaException);
                        XmlUtil.SalvarXmlNFeComErro(notaFiscal, node);
                        throw;
                    }

                    AtribuirValoresApósEnvioComSucesso(notaFiscal, qrCode, notaFiscalEntity);
                    return(idNotaCopiaSeguranca);
                }
            }
            catch (Exception e)
            {
                log.Error(e);
                //Necessário para não tentar enviar a mesma nota como contingência.
                _configuracaoService.SalvarPróximoNúmeroSérie(notaFiscal.Identificacao.Modelo,
                                                              notaFiscal.Identificacao.Ambiente);

                if (notaFiscal.Identificacao.Modelo == Modelo.Modelo55)
                {
                    throw;
                }

                var message = e.InnerException != null ? e.InnerException.Message : e.Message;
                NotaEmitidaEmContingenciaEvent(message, notaFiscal.Identificacao.DataHoraEmissao);
                return(_emiteNotaFiscalContingenciaService.EmitirNotaContingencia(notaFiscal, cscId, csc));
            }
            finally
            {
                _configuracaoService.SalvarPróximoNúmeroSérie(notaFiscal.Identificacao.Modelo,
                                                              notaFiscal.Identificacao.Ambiente);
            }
        }