/// <summary> /// Consulta lote, função acionada pelo usuário /// </summary> /// <param name="idNf"></param> public static string ConsultaLote(uint idCte) { ConhecimentoTransporte cte = ConhecimentoTransporteDAO.Instance.GetElement(idCte); ProtocoloCte protocolo = ProtocoloCteDAO.Instance.GetElement(idCte, (int)ProtocoloCte.TipoProtocoloEnum.Autorizacao); #region Monta XML de requisição de situação do lote if (protocolo == null || String.IsNullOrEmpty(protocolo.NumRecibo)) { throw new Exception("O CTe não foi emitido. Não há número de recibo."); } string strXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<consReciCTe xmlns=\"http://www.portalfiscal.inf.br/cte\" " + "versao=\"" + ConfigCTe.VersaoRetRecepcao + "\">" + "<tpAmb>" + (int)ConfigCTe.TipoAmbiente + "</tpAmb>" + "<nRec>" + protocolo.NumRecibo.PadLeft(15, '0') + "</nRec></consReciCTe>"; XmlDocument xmlRetRecep = new XmlDocument(); xmlRetRecep.LoadXml(strXml); try { ValidaXML.Validar(xmlRetRecep, ValidaXML.TipoArquivoXml.RetRecepcao); } catch (Exception ex) { throw ex; } #endregion // Guarda o status do lote string status = String.Empty; XmlNode xmlRetorno = null; // Salva o callback padrão do WebService System.Net.Security.RemoteCertificateValidationCallback callback = System.Net.ServicePointManager.ServerCertificateValidationCallback; try { // Altera o callback de validação do WebService System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors error) { // Verifica se a data do certificado é válida DateTime beginDate = DateTime.Parse(cert.GetEffectiveDateString()); DateTime endDate = DateTime.Parse(cert.GetExpirationDateString()); bool isDateValid = (DateTime.Now >= beginDate) && (DateTime.Now <= endDate); // Retorna o resultado da função return(isDateValid); }; #region Envia o arquivo e recebe o retorno var participante = ParticipanteCteDAO.Instance.GetParticipanteByIdCteTipo(cte.IdCte, (int)ParticipanteCte.TipoParticipanteEnum.Emitente); string uf = LojaDAO.Instance.GetElement(participante.IdLoja.Value).Uf.ToUpper(); if (cte.TipoEmissao == (int)Glass.Data.Model.Cte.ConhecimentoTransporte.TipoEmissaoEnum.Normal) { if (ConfigCTe.TipoAmbiente == ConfigCTe.TipoAmbienteCte.Producao) { switch (uf) { case "MT": xmlRetorno = GetWebService.PMTCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "MS": xmlRetorno = GetWebService.PMSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "MG": xmlRetorno = GetWebService.PMGCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "PR": xmlRetorno = GetWebService.PPRCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "RS": xmlRetorno = GetWebService.PRSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "SP": xmlRetorno = GetWebService.PSPCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "AP": case "PE": case "RR": xmlRetorno = GetWebService.PSVSPCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "AC": case "AL": case "AM": case "BA": case "CE": case "DF": case "ES": case "GO": case "MA": case "PA": case "PB": case "PI": case "RJ": case "RN": case "RO": case "SC": case "SE": case "TO": xmlRetorno = GetWebService.PSVRSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; } } else { switch (uf) { //case "MT": // xmlRetorno = GetWebService.HMTCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "MS": xmlRetorno = GetWebService.HMSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "MG": xmlRetorno = GetWebService.HMGCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "PR": xmlRetorno = GetWebService.HPRCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "RS": xmlRetorno = GetWebService.HRSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "SP": xmlRetorno = GetWebService.HSPCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "AP": case "PE": case "RR": xmlRetorno = GetWebService.HSVSPCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "AC": case "AL": case "AM": case "BA": case "CE": case "DF": case "ES": case "GO": case "MA": case "PA": case "PB": case "PI": case "RJ": case "RN": case "RO": case "SC": case "SE": case "TO": xmlRetorno = GetWebService.HSVRSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; } } } else if (cte.TipoEmissao == (int)Glass.Data.Model.Cte.ConhecimentoTransporte.TipoEmissaoEnum.AutorizacaoSvcRs || cte.TipoEmissao == (int)Glass.Data.Model.Cte.ConhecimentoTransporte.TipoEmissaoEnum.AutorizacaoSvcSp) { if (ConfigCTe.TipoAmbiente == ConfigCTe.TipoAmbienteCte.Producao) { switch (uf) { case "AP": case "MT": case "MS": case "PE": case "RR": case "SP": xmlRetorno = GetWebService.PSVRSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "AC": case "AL": case "AM": case "BA": case "CE": case "DF": case "ES": case "GO": case "MA": case "MG": case "PA": case "PB": case "PI": case "PR": case "RJ": case "RN": case "RO": case "RS": case "SC": case "SE": case "TO": xmlRetorno = GetWebService.PSVSPCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; } } else { switch (uf) { case "AP": case "MT": case "MS": case "PE": case "RR": case "SP": xmlRetorno = GetWebService.HSVRSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "AC": case "AL": case "AM": case "BA": case "CE": case "DF": case "ES": case "GO": case "MA": case "MG": case "PA": case "PB": case "PI": case "PR": case "RJ": case "RN": case "RO": case "RS": case "SC": case "SE": case "TO": xmlRetorno = GetWebService.HSVSPCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; } } } #endregion } catch (Exception ex) { throw new Exception(Glass.MensagemAlerta.FormatErrorMsg("Falha ao chamar WebService.", ex)); } finally { // Restaura o callback padrão para o WebService System.Net.ServicePointManager.ServerCertificateValidationCallback = callback; } // Se o lote já tiver sido processado, sai do loop if (xmlRetorno != null) // Lote processado { status = xmlRetorno["cStat"].InnerXml; } // Verifica o status do lote if (status == "104") // Lote processado { XmlNodeList protCTeList = ((XmlElement)xmlRetorno).GetElementsByTagName("protCTe"); // Para cada protocolo de autorização de uso (inicialmente será só um, pois cada nota está sendo enviada em um lote distinto) foreach (XmlNode protCTeNode in protCTeList) { ConhecimentoTransporteDAO.Instance.RetornoEmissaoCte(idCte, protCTeNode); string statusCTe = protCTeNode["infProt"]["cStat"].InnerXml; if (statusCTe == "100" || statusCTe == "150") // Autorizada para uso { Glass.Data.DAL.CTe.LogCteDAO.Instance.NewLog(idCte, "Consulta", 106, "CTe está autorizada para uso."); return("CTe está autorizado para uso."); } else { Glass.Data.DAL.CTe.LogCteDAO.Instance.NewLog(idCte, "Consulta", 106, protCTeNode["infProt"]["xMotivo"].InnerXml); return("CTe rejeitada. Motivo: " + protCTeNode["infProt"]["xMotivo"].InnerXml); } } return("Lote processado"); } else if (status == "105") // Lote em processamento { ConhecimentoTransporteDAO.Instance.AlteraSituacao(idCte, Glass.Data.Model.Cte.ConhecimentoTransporte.SituacaoEnum.ProcessoEmissao); return("Este CTe ainda está sendo processado pela SEFAZ, aguarde para realizar uma nova consulta."); } else if (status == "106") // Lote não encontrado { ConhecimentoTransporteDAO.Instance.AlteraSituacao(idCte, Glass.Data.Model.Cte.ConhecimentoTransporte.SituacaoEnum.FalhaEmitir); Glass.Data.DAL.CTe.LogCteDAO.Instance.NewLog(idCte, "Consulta", 106, "Falha na emissão do CTe. Não foi encontrado o lote de envio."); return("Falha na consulta. Não foi encontrado o lote de envio."); } else // Lote rejeitado { ConhecimentoTransporteDAO.Instance.AlteraSituacao(idCte, Glass.Data.Model.Cte.ConhecimentoTransporte.SituacaoEnum.FalhaEmitir); Glass.Data.DAL.CTe.LogCteDAO.Instance.NewLog(idCte, "Consulta", Glass.Conversoes.StrParaInt(xmlRetorno["cStat"].InnerXml), xmlRetorno["xMotivo"].InnerXml); string msgErro = "Falha na consulta. "; if (status == "215" || status == "516" || status == "517" || status == "545") { msgErro += "Mensagem de consulta inválida. "; } else if (status == "225" || status == "565" || status == "567" || status == "568") { msgErro += "Lote do CTe é inválido. "; } return(msgErro + xmlRetorno["cStat"].InnerXml + " - " + CustomizaMensagemRejeicao(idCte, xmlRetorno["xMotivo"].InnerXml)); } }
/// <summary> /// Consulta situação do lote 25 segundos após enviar o mesmo, função chamada por thread /// </summary> /// <param name="args">idCte|CertPath|CTeXmlPath</param> public static void ConsultaLoteThread(object args) { var vetParam = args.ToString().Split('|'); Glass.Data.Model.Cte.ConhecimentoTransporte cte = Glass.Data.DAL.CTe.ConhecimentoTransporteDAO.Instance.GetElement(Convert.ToUInt32(vetParam[0])); Glass.Data.Model.Cte.ProtocoloCte protocolo = Glass.Data.DAL.CTe.ProtocoloCteDAO.Instance.GetElement(Convert.ToUInt32(vetParam[0]), (int)Glass.Data.Model.Cte.ProtocoloCte.TipoProtocoloEnum.Autorizacao); try { #region Monta XML de requisição de situação do lote string strXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<consReciCTe xmlns=\"http://www.portalfiscal.inf.br/cte\" " + "versao=\"" + ConfigCTe.VersaoRetRecepcao + "\">" + "<tpAmb>" + (int)ConfigCTe.TipoAmbiente + "</tpAmb>" + "<nRec>" + protocolo.NumRecibo.PadLeft(15, '0') + "</nRec></consReciCTe>"; XmlDocument xmlRetRecep = new XmlDocument(); xmlRetRecep.LoadXml(strXml); #endregion #region Comunica com webservice // Instancia xml de retorno XmlNode xmlRetorno = null; // Salva o status do lote string status = String.Empty; // Realiza 2 tentativas de envio, se não funcionar, deixa pro usuário consultar mais tarde for (int i = 0; i < 2; i++) { try { // Espera 25 segundos para realizar a consulta do lote Thread.Sleep(25000); // Salva o callback padrão do WebService System.Net.Security.RemoteCertificateValidationCallback callback = System.Net.ServicePointManager.ServerCertificateValidationCallback; try { // Altera o callback de validação do WebService System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors error) { // Verifica se a data do certificado é válida DateTime beginDate = DateTime.Parse(cert.GetEffectiveDateString()); DateTime endDate = DateTime.Parse(cert.GetExpirationDateString()); bool isDateValid = (DateTime.Now >= beginDate) && (DateTime.Now <= endDate); // Retorna o resultado da função return(isDateValid); }; #region Envia o arquivo e recebe o retorno var participante = ParticipanteCteDAO.Instance.GetParticipanteByIdCteTipo(cte.IdCte, (int)ParticipanteCte.TipoParticipanteEnum.Emitente); string uf = LojaDAO.Instance.GetElement(participante.IdLoja.Value).Uf.ToUpper(); if (cte.TipoEmissao != (int)Glass.Data.Model.Cte.ConhecimentoTransporte.TipoEmissaoEnum.ContingenciaFsda) { if (ConfigCTe.TipoAmbiente == ConfigCTe.TipoAmbienteCte.Producao) { switch (uf) { case "MT": xmlRetorno = GetWebService.PMTCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "MS": xmlRetorno = GetWebService.PMSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "MG": xmlRetorno = GetWebService.PMGCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "PR": xmlRetorno = GetWebService.PPRCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "RS": xmlRetorno = GetWebService.PRSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "SP": xmlRetorno = GetWebService.PSPCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "AP": case "PE": case "RR": xmlRetorno = GetWebService.PSVSPCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "AC": case "AL": case "AM": case "BA": case "CE": case "DF": case "ES": case "GO": case "MA": case "PA": case "PB": case "PI": case "RJ": case "RN": case "RO": case "SC": case "SE": case "TO": xmlRetorno = GetWebService.PSVRSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; } } else { switch (uf) { //case "MT": // xmlRetorno = GetWebService.HMTCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "MS": xmlRetorno = GetWebService.HMSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "MG": xmlRetorno = GetWebService.HMGCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "PR": xmlRetorno = GetWebService.HPRCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "RS": xmlRetorno = GetWebService.HRSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "SP": xmlRetorno = GetWebService.HSPCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "AP": case "PE": case "RR": xmlRetorno = GetWebService.HSVSPCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; case "AC": case "AL": case "AM": case "BA": case "CE": case "DF": case "ES": case "GO": case "MA": case "PA": case "PB": case "PI": case "RJ": case "RN": case "RO": case "SC": case "SE": case "TO": xmlRetorno = GetWebService.HSVRSCTeRetRecepcao(cte, null).cteRetRecepcao(xmlRetRecep); break; } } } //else // xmlRetorno = GetWebService.SCANRetornoRecepcao(cte, null).nfeRetRecepcao2(xmlRetRecep); #endregion } finally { // Restaura o callback padrão para o WebService System.Net.ServicePointManager.ServerCertificateValidationCallback = callback; } // Se o lote já tiver sido processado, sai do loop if (xmlRetorno != null) // Lote processado { status = xmlRetorno["cStat"].InnerXml; } if (status == "104") { break; } } catch { } } #endregion // Se o lote já tiver sido processado, lê mensagem de retorno da consulta à situação do lote if (status == "104") { XmlNodeList protCTeList = ((XmlElement)xmlRetorno).GetElementsByTagName("protCTe"); // Para cada protocolo de autorização de uso (inicialmente será só um, pois cada nota está sendo enviada em um lote distinto) foreach (XmlNode protCTeNode in protCTeList) { ConhecimentoTransporteDAO.Instance.RetornoEmissaoCte(cte.IdCte, protCTeNode, vetParam[2]); } } } catch { } }