/// <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); } }
/// <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); }