예제 #1
0
        /// <summary>
        /// Envia a MDFe para a SEFAZ via Webservice
        /// </summary>
        /// <param name="xmlMDFe"></param>
        /// <param name="idManifestoEletronico"></param>
        public static string EnviaMDFe(XmlDocument xmlMDFe, int idManifestoEletronico)
        {
            try
            {
                // Monta o lote
                XmlDocument xmlLote = CriaLote(xmlMDFe, idManifestoEletronico);

                // Busca dados do Manifesto Eletronico
                var mdfe = ManifestoEletronicoDAO.Instance.ObterManifestoEletronicoPeloId(idManifestoEletronico);

                #region Envia XML

                // Instancia xml de retorno
                XmlNode xmlRetorno = null;

                // Salva o callback padrão do WebService
                System.Net.Security.RemoteCertificateValidationCallback callback = System.Net.ServicePointManager.ServerCertificateValidationCallback;

                // Realiza 3 tentativas de envio, se não funcionar, gera mensagem de erro
                for (int i = 0; i < 3; i++)
                {
                    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

                        if (mdfe.TipoEmissao == Glass.Data.Model.TipoEmissao.Normal)
                        {
                            if (ConfigMDFe.TipoAmbiente == ConfigMDFe.TipoAmbienteMDFe.Producao)
                            {
                                xmlRetorno = GetWebService.PSVRSMDFeRecepcao(mdfe, null).mdfeRecepcaoLote(xmlLote);
                            }
                            // TipoAmbienteMDFe.Homologacao
                            else
                            {
                                xmlRetorno = GetWebService.HSVRSMDFeRecepcao(mdfe, null).mdfeRecepcaoLote(xmlLote);
                            }
                        }
                        // TipoEmissao.Contingencia
                        else
                        {
                            if (ConfigMDFe.TipoAmbiente == ConfigMDFe.TipoAmbienteMDFe.Producao)
                            {
                                xmlRetorno = GetWebService.PSVRSMDFeRecepcao(mdfe, null).mdfeRecepcaoLote(xmlLote);
                            }
                            // TipoAmbienteMDFe.Homologacao
                            else
                            {
                                xmlRetorno = GetWebService.HSVRSMDFeRecepcao(mdfe, null).mdfeRecepcaoLote(xmlLote);
                            }
                        }

                        #endregion

                        break;
                    }
                    catch (Exception ex)
                    {
                        if (i == 3)
                        {
                            LogMDFeDAO.Instance.NewLog(idManifestoEletronico, "Emissão", 1, "Falha ao enviar lote. " + ex.Message);
                            if (mdfe.Situacao != SituacaoEnum.ContingenciaOffline)
                            {
                                ManifestoEletronicoDAO.Instance.AlteraSituacao(idManifestoEletronico, Glass.Data.Model.SituacaoEnum.FalhaEmitir);
                            }
                            return("Falha ao enviar lote. " + ex.Message);
                        }
                    }
                    finally
                    {
                        // Restaura o callback padrão para o WebService
                        System.Net.ServicePointManager.ServerCertificateValidationCallback = callback;
                    }
                }

                #endregion

                #region Lê Xml de retorno do envio do lote

                // Verifica se o Xml de Retorno é válido
                if (xmlRetorno == null)
                {
                    LogMDFeDAO.Instance.NewLog(idManifestoEletronico, "Emissão", 2, "Falha ao enviar lote. Retorno de envio do lote inválido.");

                    if (mdfe.Situacao != SituacaoEnum.ContingenciaOffline)
                    {
                        ManifestoEletronicoDAO.Instance.AlteraSituacao(idManifestoEletronico, Glass.Data.Model.SituacaoEnum.FalhaEmitir);
                    }

                    return("Falha ao enviar lote. Retorno de envio do lote inválido.");
                }

                // Lê Xml de retorno do envio do lote
                var cStat   = Conversoes.StrParaInt(xmlRetorno["cStat"].InnerXml);
                var xMotivo = xmlRetorno["xMotivo"].InnerXml;

                if (cStat == 103) // Lote recebido com sucesso
                {
                    LogMDFeDAO.Instance.NewLog(idManifestoEletronico, "Emissão", cStat, xMotivo);

                    // Pega o número do recibo do lote
                    string numReciboLote = xmlRetorno["infRec"]["nRec"].InnerXml;

                    // Salva no MDFe o número do recibo do lote
                    ManifestoEletronicoDAO.Instance.SalvaReciboProtocoloAutorizacao(idManifestoEletronico, numReciboLote);
                    return(xMotivo);
                }
                else if (cStat > 200) // Lote foi rejeitado pela SEFAZ
                {
                    LogMDFeDAO.Instance.NewLog(idManifestoEletronico, "Emissão", cStat, xMotivo);

                    if (mdfe.Situacao != SituacaoEnum.ContingenciaOffline)
                    {
                        ManifestoEletronicoDAO.Instance.AlteraSituacao(idManifestoEletronico, Glass.Data.Model.SituacaoEnum.FalhaEmitir);
                    }

                    return(xMotivo);
                }
                else
                {
                    LogMDFeDAO.Instance.NewLog(idManifestoEletronico, "Emissão", cStat, xMotivo);
                    return(xMotivo);
                }

                #endregion
            }
            catch (Exception ex)
            {
                LogMDFeDAO.Instance.NewLog(idManifestoEletronico, "Emissão", 1, MensagemAlerta.FormatErrorMsg("Falha ao enviar lote.", ex));

                return(MensagemAlerta.FormatErrorMsg("Falha ao enviar lote.", ex));
            }
        }