/// <summary>
        /// Monta o um lote para cada NFe
        /// </summary>
        /// <param name="oNfe">Objeto referente a instância da classe UniNfeClass</param>
        /// <by>Wandrey Mundin Ferreira</by>
        /// <date>17/04/2009</date>
        private void MontarLoteUmaNfe(Object oNfe)
        {
            int emp = new FindEmpresaThread(Thread.CurrentThread).Index;

            //Definir o tipo do serviço
            Type tipoServico = oNfe.GetType();

            List <string> lstArquivos = new List <string>();
            FluxoNfe      oFluxoNfe   = new FluxoNfe();

            lstArquivos = this.ArquivosPasta(Empresa.Configuracoes[emp].PastaEnvio + InfoApp.NomePastaXMLAssinado, "*" + ExtXml.Nfe);
            for (int i = 0; i < lstArquivos.Count; i++)
            {
                string cError = "";
                try
                {
                    LerXML.DadosNFeClass oDadosNfe = this.LerXMLNFe(lstArquivos[i]);
                    if (!oFluxoNfe.NFeComLote(oDadosNfe.chavenfe))
                    {
                        //Gerar lote
                        tipoServico.InvokeMember("vXmlNfeDadosMsg", System.Reflection.BindingFlags.SetProperty, null, oNfe, new object[] { lstArquivos[i] });
                        tipoServico.InvokeMember("LoteNfe", System.Reflection.BindingFlags.InvokeMethod, null, oNfe, new object[] { lstArquivos[i] });
                    }
                }
                catch (IOException ex)
                {
                    cError = (ex.InnerException != null ? ex.InnerException.Message : ex.Message);
                }
                catch (Exception ex)
                {
                    cError = (ex.InnerException != null ? ex.InnerException.Message : ex.Message);
                }
                ///
                /// danasa 9-2009
                ///
                if (!string.IsNullOrEmpty(cError))
                {
                    Auxiliar oAux = new Auxiliar();
                    ///
                    /// grava o arquivo de erro
                    ///
                    oAux.GravarArqErroERP(Path.GetFileNameWithoutExtension(lstArquivos[i]) + ".err", cError);
                    ///
                    /// move o arquivo para a pasta de erro
                    ///
                    oAux.MoveArqErro(lstArquivos[i]);
                }
            }
        }
        /// <summary>
        /// Gera o XML de consulta do recibo do lote de notas enviadas
        /// </summary>
        /// <param name="oNfe">Objeto referente a classe UniNFeClass a ser utilizado</param>
        /// <by>Wandrey Mundin Ferreira</by>
        private void GerarXMLPedRec(object oNfe)
        {
            Type tipoServico = oNfe.GetType();

            //Criar a lista dos recibos a serem consultados no SEFAZ
            List <ReciboCons> lstRecibo = new List <ReciboCons>();

            FluxoNfe oFluxoNfe = new FluxoNfe();

            try
            {
                lstRecibo = oFluxoNfe.CriarListaRec();
            }
            catch
            {
                //Não precisa fazer nada se não conseguiu criar a lista, somente con
            }

            ReciboCons oReciboCons;

            for (int i = 0; i < lstRecibo.Count; i++)
            {
                oReciboCons = lstRecibo[i];
                var tempoConsulta = oReciboCons.tMed;

                //Vou dar no mínimo 2 segundos para efetuar a consulta do recibo. Wandreu 20/07/2010
                if (tempoConsulta < 2)
                {
                    tempoConsulta = 2;
                }

                if (DateTime.Now.Subtract(oReciboCons.dPedRec).Seconds >= tempoConsulta)
                {
                    //Atualizar a tag da data e hora da ultima consulta do recibo
                    oFluxoNfe.AtualizarDPedRec(oReciboCons.nRec, DateTime.Now.AddSeconds(10));
                    tipoServico.InvokeMember("XmlPedRec", System.Reflection.BindingFlags.InvokeMethod, null, oNfe, new object[] { oReciboCons.nRec });
                }
            }
        }
        /// <summary>
        /// Monta o um lote com várias NFe´s
        /// </summary>
        /// <param name="oNfe">Objeto referente a instância da classe absServicoNFe</param>
        /// <by>Wandrey Mundin Ferreira</by>
        /// <date>28/04/2009</date>
        private void MontarLoteVariasNfe(Object oNfe)
        {
            int emp = new FindEmpresaThread(Thread.CurrentThread).Index;

            List <string> lstArqMontarLote = new List <string>();

            //Aguardar a assinatura de todos os arquivos da pasta de lotes
            lstArqMontarLote = this.ArquivosPasta(Empresa.Configuracoes[emp].PastaEnvioEmLote, "*" + ExtXml.Nfe);
            if (lstArqMontarLote.Count > 0)
            {
                return;
            }

            //Verificar se existe o arquivo que solicita a montagem do lote
            lstArqMontarLote = this.ArquivosPasta(Empresa.Configuracoes[emp].PastaEnvioEmLote, "*" + ExtXml.MontarLote);

            for (int b = 0; b < lstArqMontarLote.Count; b++)
            {
                string NomeArquivo = lstArqMontarLote[b];

                //O arquivo existe mas pode estar em uso
                if (Auxiliar.FileInUse(NomeArquivo) == true)
                {
                    return;
                }

                Auxiliar      oAux      = new Auxiliar();
                List <string> lstNfe    = new List <string>();
                FileStream    fsArquivo = null;
                FluxoNfe      oFluxoNfe = new FluxoNfe();

                string MensagemErro = string.Empty;
                bool   lTeveErro    = false;

                try
                {
                    XmlDocument doc = new XmlDocument();                                                          //Criar instância do XmlDocument Class
                    fsArquivo = new FileStream(NomeArquivo, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); //Abrir um arquivo XML usando FileStream
                    doc.Load(fsArquivo);                                                                          //Carregar o arquivo aberto no XmlDocument

                    XmlNodeList documentoList = doc.GetElementsByTagName("MontarLoteNFe");                        //Pesquisar o elemento Documento no arquivo XML
                    foreach (XmlNode documentoNode in documentoList)
                    {
                        XmlElement documentoElemento = (XmlElement)documentoNode;

                        int QtdeArquivo = documentoElemento.GetElementsByTagName("ArquivoNFe").Count;

                        for (int d = 0; d < QtdeArquivo; d++)
                        {
                            string ArquivoNFe = Empresa.Configuracoes[emp].PastaEnvioEmLote + InfoApp.NomePastaXMLAssinado + "\\" + documentoElemento.GetElementsByTagName("ArquivoNFe")[d].InnerText;

                            if (File.Exists(ArquivoNFe))
                            {
                                try
                                {
                                    LerXML.DadosNFeClass oDadosNfe = this.LerXMLNFe(ArquivoNFe);
                                    if (!oFluxoNfe.NFeComLote(oDadosNfe.chavenfe))
                                    {
                                        lstNfe.Add(ArquivoNFe);
                                    }
                                    else
                                    {
                                        MensagemErro += "Arquivo: " + ArquivoNFe + " já está no fluxo de envio e não será incluido em novo lote.\r\n";
                                        lTeveErro     = true;

                                        FileInfo oArq = new FileInfo(ArquivoNFe);
                                        oArq.Delete();
                                    }
                                }
                                catch (IOException ex)
                                {
                                    MensagemErro += ex.Message + "\r\n";
                                    lTeveErro     = true;
                                }
                                catch (Exception ex)
                                {
                                    MensagemErro += ex.Message + "\r\n";
                                    lTeveErro     = true;
                                }
                            }
                            else
                            {
                                lTeveErro     = true;
                                MensagemErro += "Arquivo: " + ArquivoNFe + " não existe e não será incluido no lote!\r\n";
                            }
                        }
                    }

                    fsArquivo.Close(); //Fecha o arquivo XML

                    //Definir o tipo do serviço
                    Type tipoServico = oNfe.GetType();

                    try
                    {
                        //Gerar lote
                        tipoServico.InvokeMember("LoteNfe", System.Reflection.BindingFlags.InvokeMethod, null, oNfe, new object[] { lstNfe });
                    }
                    catch (IOException ex)
                    {
                        MensagemErro += ex.Message + "\r\n";
                        lTeveErro     = true;
                    }
                    catch (Exception ex)
                    {
                        MensagemErro += ex.Message + "\r\n";
                        lTeveErro     = true;
                    }
                }
                catch (Exception ex)
                {
                    if (fsArquivo != null)
                    {
                        fsArquivo.Close();
                    }

                    lTeveErro     = true;
                    MensagemErro += ex.Message + "\r\n";
                }

                //Deletar o arquivo de solicitão de montagem do lote de NFe
                try
                {
                    FileInfo oArquivo = new FileInfo(NomeArquivo);
                    oArquivo.Delete();
                }
                catch (IOException ex)
                {
                    lTeveErro     = true;
                    MensagemErro += ex.Message + "\r\n";
                }
                catch (Exception ex)
                {
                    lTeveErro     = true;
                    MensagemErro += ex.Message + "\r\n";
                }

                if (lTeveErro)
                {
                    try
                    {
                        oAux.GravarArqErroServico(NomeArquivo, ExtXml.MontarLote, "-montar-lote.err", MensagemErro);
                    }
                    catch
                    {
                        //Se deu algum erro na hora de gravar o arquivo de erro de retorno para o ERP, infelizmente não poderemos fazer nada
                        //pois deve estar ocorrendo alguma falha de rede, hd, permissão de acesso a pasta ou arquivos, etc. Wandrey 22/03/2010
                    }
                }
            }
        }
        private const int _Minutos = 10;  //10 minutos?

        public NFeEmProcessamento()
        {
            int emp = new FindEmpresaThread(Thread.CurrentThread).Index;

            if (Empresa.Configuracoes[emp].UltimaVerificacaoEmProcessamento.Year > 1)
            {
                ///
                /// executa de 10x10 minutos para evitar ter que acessar o HD sem necessidade
                ///
                DateTime dCheck = Empresa.Configuracoes[emp].UltimaVerificacaoEmProcessamento.AddMinutes(_Minutos);
                if (dCheck > DateTime.Now)
                {
                    return;
                }
            }

            Empresa.Configuracoes[emp].UltimaVerificacaoEmProcessamento = DateTime.Now;
            this.oAux = new Auxiliar();

            try
            {
                ///
                /// le todos os arquivos que estão na pasta em processamento
                ///
                string[] files = Directory.GetFiles(Empresa.Configuracoes[emp].PastaEnviado + "\\" + PastaEnviados.EmProcessamento.ToString(),
                                                    "*" + ExtXml.Nfe,
                                                    SearchOption.TopDirectoryOnly);
                ///
                /// considera os arquivos em que a data do ultimo acesso é superior a 10 minutos
                ///
                DateTime UltimaData = DateTime.Now.AddMinutes(-_Minutos);

                foreach (string file in files)
                {
                    if (!Auxiliar.FileInUse(file))
                    {
                        FileInfo fi = new FileInfo(file);

                        //usar a última data de acesso, e não a data de criação
                        if (fi.LastWriteTime <= UltimaData)
                        {
                            if (this.oLerXml == null)
                            {
                                this.oLerXml   = new LerXML();
                                this.oGerarXml = new GerarXML(emp);
                                this.fluxo     = new FluxoNfe();
                            }

                            try
                            {
                                //Ler a NFe
                                oLerXml.Nfe(file);

                                //Verificar se o -nfe.xml existe na pasta de autorizados
                                bool NFeJaNaAutorizada = oAux.EstaAutorizada(file, oLerXml.oDadosNfe.dEmi, ExtXml.Nfe);

                                //Verificar se o -procNfe.xml existe na past de autorizados
                                bool procNFeJaNaAutorizada = oAux.EstaAutorizada(file, oLerXml.oDadosNfe.dEmi, ExtXmlRet.ProcNFe);

                                //Se um dos XML´s não estiver na pasta de autorizadas ele força finalizar o processo da NFe.
                                if (!NFeJaNaAutorizada || !procNFeJaNaAutorizada)
                                {
                                    //Verificar se a NFe está no fluxo, se não estiver vamos incluir ela para que funcione
                                    //a rotina de gerar o -procNFe.xml corretamente. Wandrey 21/10/2009
                                    if (!fluxo.NfeExiste(oLerXml.oDadosNfe.chavenfe))
                                    {
                                        fluxo.InserirNfeFluxo(oLerXml.oDadosNfe.chavenfe, oAux.ExtrairNomeArq(file, ExtXml.Nfe) + ExtXml.Nfe);
                                    }

                                    //gera um -ped-sit.xml mesmo sendo autorizada ou denegada, pois assim sendo, o ERP precisaria dele
                                    string vArquivoSit = oLerXml.oDadosNfe.chavenfe.Substring(3);

                                    oGerarXml.Consulta(vArquivoSit + ExtXml.PedSit,
                                                       Convert.ToInt32(oLerXml.oDadosNfe.tpAmb),
                                                       Convert.ToInt32(oLerXml.oDadosNfe.tpEmis),
                                                       oLerXml.oDadosNfe.chavenfe.Substring(3));
                                }
                                else
                                {
                                    //Move o XML da pasta em processamento para a pasta de XML´s com erro (-nfe.xml)
                                    oAux.MoveArqErro(file);

                                    //Move o XML da pasta em processamento para a pasta de XML´s com erro (-procNFe.xml)
                                    oAux.MoveArqErro(Empresa.Configuracoes[emp].PastaEnviado + "\\" + PastaEnviados.EmProcessamento.ToString() + "\\" + oAux.ExtrairNomeArq(file, ExtXml.Nfe) + ExtXmlRet.ProcNFe);

                                    //Tirar a nota fiscal do fluxo
                                    fluxo.ExcluirNfeFluxo(oLerXml.oDadosNfe.chavenfe);
                                }
                            }
                            catch (Exception ex)
                            {
                                ///
                                /// grava o arquivo com extensao .ERR
                                ///
                                oAux.GravarArqErroERP(Path.GetFileNameWithoutExtension(file) + ".err", ex.Message);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ///
                /// grava o arquivo generico
                ///
                oAux.GravarArqErroERP(string.Format(InfoApp.NomeArqERRUniNFe, DateTime.Now.ToString("yyyyMMddThhmmss")), ex.Message);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Assinar e validar o XML da Nota Fiscal Eletrônica e move para a pasta de assinados
        /// </summary>
        /// <param name="bMoverXML">true = Mover XML assinado da pasta de Lote para a subpasta Assinado</param>
        /// <param name="strPasta">Nome da pasta onde está o XML a ser validado e assinado</param>
        /// <returns>true = Conseguiu assinar e validar</returns>
        /// <by>Wandrey Mundin Ferreira</by>
        /// <date>03/04/2009</date>
        public Boolean AssinarValidarXMLNFe(string strPasta)
        {
            int emp = new FindEmpresaThread(Thread.CurrentThread).Index;

            Boolean bRetorna        = false;
            Boolean bAssinado       = this.Assinado(this.vXmlNfeDadosMsg);
            Boolean bValidadoSchema = false;
            Boolean bValidacaoGeral = false;

            //Criar Pasta dos XML´s a ser enviado em Lote já assinados
            string strPastaLoteAssinado = strPasta + InfoApp.NomePastaXMLAssinado;

            //Se o arquivo XML já existir na pasta de assinados, vou avisar o ERP que já tem um em andamento
            string strArqDestino = strPastaLoteAssinado + "\\" + oAux.ExtrairNomeArq(this.vXmlNfeDadosMsg, ".xml") + ".xml";

            try
            {
                //Fazer uma leitura de algumas tags do XML
                LerXML.DadosNFeClass oDadosNFe = this.LerXMLNFe(this.vXmlNfeDadosMsg);
                string ChaveNfe = oDadosNFe.chavenfe;
                string TpEmis   = oDadosNFe.tpEmis;

                //Inserir NFe no XML de controle do fluxo
                try
                {
                    FluxoNfe oFluxoNfe = new FluxoNfe();
                    if (oFluxoNfe.NfeExiste(ChaveNfe))
                    {
                        //Mover o arquivo da pasta em processamento para a pasta de XML´s com erro
                        oAux.MoveArqErro(Empresa.Configuracoes[emp].PastaEnviado + "\\" + PastaEnviados.EmProcessamento.ToString() + "\\" + oAux.ExtrairNomeArq(this.vXmlNfeDadosMsg, ".xml") + ".xml");

                        //Deletar a NFE do arquivo de controle de fluxo
                        oFluxoNfe.ExcluirNfeFluxo(ChaveNfe);

                        //Vou forçar uma exceção, e o ERP através do inicio da mensagem de erro pode tratar e já gerar uma consulta
                        //situação para finalizar o processo. Assim envito perder os XML´s que estão na pasta EmProcessamento
                        //tendo assim a possibilidade de gerar o -procNfe.XML através da consulta situação.
                        //Wandrey 08/10/2009
                        //throw new Exception("NFE NO FLUXO: Esta nota fiscal já está na pasta de Notas Fiscais em processo de envio, desta forma não é possível envia-la novamente. Se a nota fiscal estiver presa no fluxo de envio sem conseguir finalizar o processo, gere um consulta situação da NFe para forçar a finalização.\r\n" +
                        //    this.vXmlNfeDadosMsg);
                    }
                    else
                    {
                        //Deletar o arquivo XML da pasta de temporários de XML´s com erros se o mesmo existir
                        oAux.DeletarArqXMLErro(Empresa.Configuracoes[emp].PastaErro + "\\" + oAux.ExtrairNomeArq(this.vXmlNfeDadosMsg, ".xml") + ".xml");
                    }

                    //Validações gerais
                    if (this.ValidacoesGeraisXMLNFe(this.vXmlNfeDadosMsg, oDadosNFe))
                    {
                        bValidacaoGeral = true;
                    }

                    //Assinar o arquivo XML
                    if (bValidacaoGeral && !bAssinado)
                    {
                        AssinaturaDigital oAD = new AssinaturaDigital();

                        ValidarXMLs oValidador = new ValidarXMLs();
                        oValidador.TipoArquivoXML(this.vXmlNfeDadosMsg);

                        oAD.Assinar(this.vXmlNfeDadosMsg, oValidador.TagAssinar, Empresa.Configuracoes[emp].X509Certificado);

                        bAssinado = true;
                    }

                    // Validar o Arquivo XML da NFe com os Schemas se estiver assinado
                    if (bValidacaoGeral && bAssinado)
                    {
                        string cResultadoValidacao = oAux.ValidarArqXML(this.vXmlNfeDadosMsg);
                        if (cResultadoValidacao == "")
                        {
                            bValidadoSchema = true;
                        }
                        else
                        {
                            //Registrar o erro da validação do schema para o sistema ERP
                            throw new Exception(cResultadoValidacao);
                        }
                    }

                    //Mover o arquivo XML da pasta de lote para a pasta de XML´s assinados
                    if (bValidadoSchema)
                    {
                        try
                        {
                            //Se a pasta de assinados não existir, vamos criar
                            if (!Directory.Exists(strPastaLoteAssinado))
                            {
                                Directory.CreateDirectory(strPastaLoteAssinado);
                            }

                            if (!File.Exists(strArqDestino))
                            {
                                //Mover o arquivo para a pasta de XML´s assinados
                                FileInfo oArquivo = new FileInfo(this.vXmlNfeDadosMsg);
                                oArquivo.MoveTo(strArqDestino);

                                bRetorna = true;
                            }
                            else
                            {
                                oFluxoNfe.InserirNfeFluxo(ChaveNfe, oAux.ExtrairNomeArq(strArqDestino, ".xml") + ".xml");

                                throw new IOException("Esta nota fiscal já está na pasta de Notas Fiscais assinadas e em processo de envio, desta forma não é possível enviar a mesma novamente.\r\n" +
                                                      this.vXmlNfeDadosMsg);
                            }
                        }
                        catch (IOException ex)
                        {
                            throw (ex);
                        }
                        catch (Exception ex)
                        {
                            throw (ex);
                        }
                    }

                    if (bRetorna)
                    {
                        try
                        {
                            oFluxoNfe.InserirNfeFluxo(ChaveNfe, oAux.ExtrairNomeArq(strArqDestino, ".xml") + ".xml");
                        }
                        catch (Exception ex)
                        {
                            throw (ex);
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw (ex);
                }
            }
            catch (Exception ex)
            {
                try
                {
                    oAux.GravarArqErroServico(this.vXmlNfeDadosMsg, ExtXml.Nfe, ExtXmlRet.Nfe_ERR, ex.Message);

                    //Se já foi movido o XML da Nota Fiscal para a pasta em Processamento, vou ter que
                    //forçar mover para a pasta de XML com erro neste ponto.
                    oAux.MoveArqErro(strArqDestino);
                }
                catch
                {
                    //Se ocorrer algum erro na hora de tentar gravar o XML de erro para o ERP ou mover o arquivo XML para a pasta de XML com erro, não
                    //vou poder fazer nada, pq foi algum erro de rede, permissão de acesso a pasta ou arquivo, etc.
                    //Wandey 13/03/2010
                }
            }

            return(bRetorna);
        }