public JsonResult ConsultaSapiens(string CPFCNPJ, int codCliente)
        {
            // VERIFICAR SE O CNPJ ou CPF é de um cliente existente
            using (var clienteSapiensBLL = new ClienteSapiensBLL())
            {
                var carSapBLL = new CaracteristicaSapiensBLL();
                var historicosBLL = new HistoricoSolicitacaoBLL();

                bool pertenceAFilial = false;
                try
                {
                    int codFilial = Convert.ToInt32(Session["CodigoFilial"]);
                    ClienteSapiens cliente = null;

                    var consultaReceitaBLL = new ConsultaReceitaBLL();

                    // RETIRA OS CARACTERES ESPECIAIS.
                    CPFCNPJ = Regex.Replace(CPFCNPJ, @"(\s+)|(\\+)|(\.+)|(/+)|(\-+)", "");

                    #region Valida CPF e CNPJ

                    if (!ValidaDocumento(CPFCNPJ))
                    {
                        return Json(new { erro = "CPF ou CNPJ Inválido" }, JsonRequestBehavior.DenyGet);
                    }

                    #endregion

                    List<ClienteSapiens> clientesSapiens = null;

                    if (codCliente != 0)
                    {
                        clientesSapiens = clienteSapiensBLL.ObterTodosPorCodigo(codCliente, ref clientes);
                    }
                    else
                    {
                        if (CPFCNPJ.Length != 0)
                        {
                            clientesSapiens = clienteSapiensBLL.ObterPorCPFCNPJ(CPFCNPJ, ref clientes); //pega todas as definições deste CPFCNPJ
                        }
                        else
                        {
                            throw new Exception("Nenhum dado encontrado para esta consulta.");
                        }
                    }

                    // se tiver mais de 1, dar a opção de importar, dando prioridade para a matriz
                    if (clientesSapiens.Count > 0)
                    {

                        // verifica se o codFil de algum dos clientes com o CPFCNPJ passado é igual ao do usuário
                        var queryClienteMesmaFilial = from c in clientesSapiens
                                                      where c.codfil == codFilial
                                                      select c.codcli;

                        if (queryClienteMesmaFilial.Count() != 0)
                        {
                            pertenceAFilial = true;

                            cliente = clienteSapiensBLL.ObterPorCodigos(queryClienteMesmaFilial.First(), codFilial);
                            //Session["Cliente"] = cliente;
                        }
                        else
                        {
                            // se o cliente existe, mas não tem registro nesta filial, sugerir a DUPLICAÇÃO

                            // se existir na matriz, usar este, senão, pegar o primeiro

                            var matrix = from c in clientesSapiens
                                         where c.codfil == 1
                                         select c;

                            if (matrix.Count() > 0)
                            {
                                cliente = matrix.First();
                            }
                            else
                            {
                                cliente = clientesSapiens[0];
                            }
                            cliente = clienteSapiensBLL.ObterPorCodigos(cliente.codcli, cliente.codfil);
                            //Session["Cliente"] = cliente;

                            // sugerir a duplicação do cliente escolhido.

                            return Json(new { msg = "Este cliente já possui registro em outra filial." }, JsonRequestBehavior.DenyGet);
                        }
                    }

                    var solicitacaoBLL = new SolicitacaoBLL();

                    //obter a data da ultima consulta ao serasa.

                    if (cliente != null)
                    {
                        // se entrar aqui, é porque o cliente foi encontrado na base do sapiens, ou seja, é ou foi cliente.
                        #region retorna um JSON com o resultado da consulta do Sapiens, para preencher todos os campos da solicitação.

                        #region Verificar se já existe solicitação para o cliente encontrado.

                        var solicitacoes = solicitacaoBLL.ObterSolicitacoesPorCodFilial(codFilial);

                        var queryClienteSolicitacao = from sol in solicitacoes
                                                      where sol.CodCliente == cliente.codcli
                                                      select sol;

                        var solicitacaoRecente = queryClienteSolicitacao.LastOrDefault();

                        if (solicitacaoRecente != null)
                        {
                            //var historicoSolicitacaoRecente = historicosBLL.ObterPorCodSolicitacao(solicitacaoRecente.Codigo).LastOrDefault();
                            var historicoSolicitacaoRecente = solicitacaoRecente.Historicos.OrderBy(h => h.CodHistoricoSolicitacao).LastOrDefault();

                            // Gilberto - 23/11/2015 - 09:51:00
                            if (historicoSolicitacaoRecente != null)
                            {
                                var situacao = historicoSolicitacaoRecente.CodSituacaoSolicitacao;

                                var temSolicitacaoAberta = situacao == Convert.ToInt32(SituacaoSolicitacao.AguardandoFechamento) || situacao == Convert.ToInt32(SituacaoSolicitacao.AguardandoAprovacao) || situacao == Convert.ToInt32(SituacaoSolicitacao.NaoIntegrada);

                                //já existe solicitação para este cliente.
                                if (temSolicitacaoAberta)
                                {
                                    return Json(new { erro = "Já existe uma solicitação aberta para o cliente pesquisado." }, JsonRequestBehavior.DenyGet);
                                }
                            }
                            else
                            {
                                return Json(new { erro = "Já existe uma solicitação para o cliente pesquisado. (aguardando fechamento)" }, JsonRequestBehavior.DenyGet);
                            }

                        }

                        #endregion

                        var s = Session["Solicitacao"] as Solicitacao;

                        s.CodTipoSolicitacao = Convert.ToInt32(TipoSolicitacao.Alteracao);
                        s.Cliente = String.IsNullOrEmpty(cliente.nomcli) ? cliente.apecli : cliente.nomcli;
                        s.CodCliente = cliente.codcli;
                        s.DatAlteracao = DateTime.Now;

                        // se pertencer a filial, copiar também os dados de endereços de cobrança e entrega, contatos, referencias e socios
                        ConsultaReceita dadosUltimaConsulta = null;
                        DateTime dataUltimaConsulta = new DateTime(1983, 4, 28);

                        solicitacaoBLL.PreencheDadosSolicitacaoUsandoSapiens(s, cliente, pertenceAFilial);

                        if (cliente.cgccpf != null && cliente.cgccpf != 0)
                        {
                            var cgccpf = cliente.cgccpf.ToString();

                            cgccpf = AjustaCPFCNPJComZerosNaFrente(cgccpf);

                            dadosUltimaConsulta = consultaReceitaBLL.ObterDadosUltimaConsultaPorDocumento(cgccpf);
                            dataUltimaConsulta = dadosUltimaConsulta != null ? dadosUltimaConsulta.Datcon : new DateTime(1983, 4, 28);
                        }

                        Session["Solicitacao"] = s;

                        var clienteSapiensJson = new
                        {
                            /* DADOS PRINCIPAIS */
                            CPFCNPJ = cliente.cgccpf.ToString(),
                            TipoCliente = cliente.tipcli as string,
                            CodCliente = cliente.codcli,
                            SituacaoReceita = dadosUltimaConsulta == null ? "" : dadosUltimaConsulta.Sitrec as string,
                            SituacaoSin = dadosUltimaConsulta == null ? "" : dadosUltimaConsulta.Sitsin as string,
                            NomeFantasia = cliente.apecli as string,
                            RazaoSocial = cliente.nomcli as string,
                            DataUltimaConsulta = dataUltimaConsulta != null ? dataUltimaConsulta : new DateTime(),
                            Logradouro = cliente.endcli as string,
                            Numero = cliente.nencli as string,
                            Complemento = cliente.cplend as string,
                            Bairro = cliente.baicli as string,
                            Cidade = cliente.cidcli as string,
                            UF = cliente.sigufs as string,
                            CEP = cliente.cepcli as int?,
                            Telefone = cliente.foncli as string,
                            Telefone2 = cliente.foncl2 as string,
                            Telefone3 = cliente.foncl3 as string,
                            Telefone4 = cliente.foncl4 as string,
                            Telefone5 = cliente.foncl5 as string,
                            NumeroFax = cliente.faxcli as string,
                            DataAbertura = cliente.datcad as DateTime?,
                            Ativo = cliente.sitcli as string,
                            InscricaoEstadualSin = cliente.insest as string,
                            CodTipoMercado = cliente.tipmer as string,
                            CodTipoEmpresa = cliente.tipemp as short?,
                            CodTipoDireitoPropriedade = cliente.tipemc as short?,
                            CodRamoAtividade = cliente.codram as string,
                            CodRamoFiscal = cliente.usuRamofiscal as string,
                            CodRota = cliente.codroe as string,
                            CodSubRota = cliente.codsro as string,
                            CodGrupoEmpresa = cliente.codgre as short?,
                            CodIBGE = cliente.zipcod as string,
                            TributaICMS = cliente.triicm as string,
                            CobraCliente = cliente.usuCobcli as string,
                            ExpurgaDaInadimplencia = cliente.usuExpina as string,
                            ObservacaoMotivoSituacao = cliente.obsmot as string,
                            EmailNFE = cliente.emanfe == null ? "" : cliente.emanfe.IndexOf(";") != -1 ? cliente.emanfe.Split(';')[0] : cliente.emanfe,
                            EmailNFE2 = cliente.emanfe == null ? "" : cliente.emanfe.IndexOf(";") != -1 ? cliente.emanfe.Split(';')[1] : "",
                            /* DEFINIÇÕES*/
                            VlrLimite = cliente.Definicoes[0] != null ? cliente.Definicoes[0].limite.ToString() : "",
                            NomCategoria = cliente.Definicoes[0] != null ? cliente.Definicoes[0].Catcli.ToString() : "-",
                            CodFormaDePagamento = cliente.Definicoes[0].Codfpg != 0 ? cliente.Definicoes[0].Codfpg.ToString() : "-",
                            CodGrupoContasAReceber = cliente.Definicoes[0] != null ? cliente.Definicoes[0].Codcrp : "-",
                            IndAceitaFaturamentoParcialPedido = cliente.Definicoes[0] != null ? cliente.Definicoes[0].Acepar : "-",
                            IndLimiteAprovado = cliente.Definicoes[0] != null ? cliente.Definicoes[0].Limapr : "-",
                            CodCondicaoPagamento = cliente.Definicoes[0] != null ? cliente.Definicoes[0].Codcpg : "-",
                            CodRepresentante = cliente.Definicoes[0].Codrep != 0 ? cliente.Definicoes[0].Codrep.ToString() : "-",
                            CodRegiaoDeVendas = cliente.Definicoes[0] != null ? cliente.Definicoes[0].Codrve : "-",
                            RecJurosMoraMes = cliente.Definicoes[0].Recjmm != 0 ? cliente.Definicoes[0].Recjmm.ToString() : "-",
                            TipJuros = cliente.Definicoes[0] != null ? cliente.Definicoes[0].Rectjr : "-",
                            IndCobrarTaxaBanco = cliente.Definicoes[0] != null ? cliente.Definicoes[0].UsuCbtban : "-",
                            IndEmiteBoleto = cliente.Definicoes[0] != null ? cliente.Definicoes[0].UsuEmitebol : "-",
                            IndDescontoFinanceiro = "0",
                        };

                        return Json(clienteSapiensJson, JsonRequestBehavior.DenyGet);

                        #endregion
                    }
                    else
                    {
                        // SE ENTRAR AQUI, TRATA-SE DE UM NOVO CLIENTE.
                        var s = Session["Solicitacao"] as Solicitacao;

                        s.CodTipoSolicitacao = Convert.ToInt32(TipoSolicitacao.Inclusao);
                        s.CodCliente = 0; // TODO: Testar se um possível BUG  se origina aqui.(Cliente existente com código 0)
                        s.DatAlteracao = DateTime.Now;
                        s.DadosPrincipaisSolicitacao.Last().Ativo = "A";

                        Session["Solicitacao"] = s;
                        return Json(new { erro = "Cliente não encontrado.", CodCliente = 0 }, JsonRequestBehavior.DenyGet);
                    }
                }
                catch (Exception ex)
                {
                    return Json(new { erro = ex.Message }, JsonRequestBehavior.DenyGet);
                }
            }// fim do using
        }
        public ActionResult EnviarParaAprovacao(string textoParecer)
        {
            using (var historicoBLL = new HistoricoSolicitacaoBLL())
            {
                var parecerSolicitacaoBLL = new ParecerSolicitacaoBLL();
                var configBLL = new ConfiguracaoWorkflowBLL();

                var s = Session["Solicitacao"] as Solicitacao;

                try
                {
                    s.TxtJustificativa = textoParecer;

                    #region Faz a configuração para o workflow

                    var config = new ConfiguracaoWorkflow();

                    //s.CodTipoSolicitacao =

                    config.StrUsuAlcada = String.IsNullOrEmpty(s.Definicoes.Last().VlrLimite) ? "0" : s.Definicoes.Last().VlrLimite.ToString(); //obter o valor do limite.
                    config.StrUsuAlcadamax = String.IsNullOrEmpty(s.Definicoes.Last().VlrLimite) ? "0" : s.Definicoes.Last().VlrLimite.ToString();
                    config.StrUsuTipsol = Convert.ToInt32(TipoSolicitacao.Inclusao).ToString();
                    config.UsuTipsol = Convert.ToInt32(TipoSolicitacao.Inclusao); // SEMPRE INCLUSÃO para o workflow.

                    config.UsuAlcada = Convert.ToDouble(config.StrUsuAlcada);
                    config.UsuAlcadamax = Convert.ToDouble(config.StrUsuAlcadamax);
                    config = configBLL.ObterConfiguracao(config, true);

                    s.nivelMaximo = configBLL.ObterNivel(config);
                    //config.UsuNivel = configBLL.ObterNivel(config);
                    #endregion

                    #region Salvar o parecer, um novo registro no histórico, e os dados do parecer.

                    // gravar o Primeiro parecer (primeiro parecer de solicitação, e o 'aprovador' será definido pela configuração.)
                    var p = new ParecerSolicitacao();

                    var historico = new HistoricoSolicitacao();

                    // Mudar da situação 'DIGITANDO - 1' para 'AGUARDANDO APROVAÇÃO - 2'
                    historico.CodSituacaoSolicitacao = Convert.ToInt32(SituacaoSolicitacao.AguardandoAprovacao);
                    historico.DatEncaminhamento = DateTime.Now;
                    historico.Solicitacao = s;
                    s.CodSituacaoAtual = Convert.ToInt32(SituacaoParecer.AguardandoAprovacao);

                    //pegar a última.
                    //s.nivelMaximo = config.UsuNivel;
                    new SolicitacaoBLL().Atualizar(s);

                    p.Solicitacao = s;
                    p.Codperusu = 2; // o perfil do analista de crédito. -> se o usuário não tiver perfil, avisar na tela.
                    p.Codusuapr = s.CodUsuarioSolicitacao; // obter o codigo do usuario da aprovacao. OK
                    //p.Datpar = historico.DatEncaminhamento;
                    p.Codsitpar = Convert.ToInt32(SituacaoParecer.AguardandoAprovacao);

                    if (!String.IsNullOrEmpty(s.TxtJustificativa))
                    {
                        parecerSolicitacaoBLL.PreencheParecerComDadosSolicitacao(p, s);
                        parecerSolicitacaoBLL.Salvar(p);

                        // Salvar o histórico da solicitação
                        historicoBLL.Salvar(historico);
                    }
                    else
                    {
                        throw new Exception("A Justificativa da Solicitação não foi encontrada.");
                    }

                    #endregion

                    // return Json(new { msg = "Envio da solicitação nº " + s.Codigo + " para aprovação foi realizado com sucesso." }, JsonRequestBehavior.DenyGet);

                    // (atualiza os grids de todos os usuários logados , sem necessidade do F5)
                    var context = GlobalHost.ConnectionManager.GetHubContext<StatusHub>();
                    context.Clients.All.AtualizarGrid();

                    return RedirectToAction("Index", "Solicitacao");

                }
                catch (Exception ex)
                {
                    return Json(new { msg = "Não foi possível enviar a Solicitação nº " + s.Codigo + " para aprovação. ERRO -> " + ex.Message }, JsonRequestBehavior.DenyGet);
                }
            }
        }
        public ActionResult SalvarDadoPrincipal(DadoPrincipalSolicitacao dps)
        {
            //Autentica
            if (Session["ConexaoSapiens"] == null)
            {
                return RedirectToAction("Login", "Home");
            }

            //Autoriza
            if (!AutorizaUsuario(Helpers.ControlAccessConfig.NovaSolicitacao))
            {
                return View("Erro", null, "Módulo não autorizado para este usuário. ");
            }

            Solicitacao s = Session["Solicitacao"] as Solicitacao;

            // pegar o valor das dropdowns com jquery, e adicionar no "data" da request ajax. FEITO. 11/11/2014
            #region preenche variáveis que não podem ficar nulas.

            if (String.IsNullOrEmpty(dps.Telefone))
            {
                dps.Telefone = "";
            }
            else
            {
                dps.Telefone = Regex.Replace(dps.Telefone, @"(\)+)|(\(+)|(\-+)", "");
                if (dps.Telefone[2] == '0')
                {
                    var ddd = dps.Telefone.Substring(0, 2);
                    var num = dps.Telefone.Substring(2);

                    dps.Telefone = ddd + num;
                }
            }

            dps.Telefone2 = String.IsNullOrEmpty(dps.Telefone2) ? "" : dps.Telefone2;
            dps.Telefone3 = String.IsNullOrEmpty(dps.Telefone3) ? "" : dps.Telefone3;
            dps.Telefone4 = String.IsNullOrEmpty(dps.Telefone4) ? "" : dps.Telefone4;
            dps.Telefone5 = String.IsNullOrEmpty(dps.Telefone5) ? "" : dps.Telefone5;

            //dps.ContribuinteICMS = String.IsNullOrEmpty(dps.ContribuinteICMS) ? "" : dps.ContribuinteICMS;
            var IE = String.IsNullOrEmpty(dps.InscricaoEstadual) ? "" : dps.InscricaoEstadual;

            dps.ContribuinteICMS = IE.Trim().ToLower() == "isento" || IE.Trim().ToLower() == "" ? "N" : "S";

            dps.TributaICMS = "S";
            dps.CodGrupoEmpresa = String.IsNullOrEmpty(dps.CodGrupoEmpresa) ? "" : dps.CodGrupoEmpresa;
            dps.NumeroFax = String.IsNullOrEmpty(dps.NumeroFax) ? "" : dps.NumeroFax;
            dps.PontoDeReferencia = string.IsNullOrEmpty(dps.PontoDeReferencia) ? "" : dps.PontoDeReferencia;

            dps.CodClienteDadoPrincipalSol = s.CodCliente;
            dps.TipoMercado = "I";
            dps.CobraCliente = "S";
            dps.ExpurgaDaInadimplencia = "N";
            dps.ObservacaoMotivoSituacao = string.IsNullOrEmpty(dps.ObservacaoMotivoSituacao) ? "" : dps.ObservacaoMotivoSituacao;
            dps.TipoDireitoPropriedadeEmpresa = "1";

            s.CodFilial = Convert.ToInt32(Session["CodigoFilial"]); // obter a filial no sapiens... OK

            #endregion

            try
            {
                var tiposDeAlteracao = dps.Alteracoes;

                //salvar os tipos de alteração.

                var usuario = (UsuarioSapiens)Session["ConexaoSapiens"];
                s.CodUsuarioSolicitacao = usuario.Codusu;
                s.DatAlteracao = DateTime.Now;

                using (SolicitacaoBLL solicitacaoBLL = new SolicitacaoBLL())
                {
                    DadoPrincipalSolicitacaoBLL dadoPrincipalBLL = new DadoPrincipalSolicitacaoBLL();
                    HistoricoSolicitacaoBLL historicoBLL = new HistoricoSolicitacaoBLL();
                    DocumentoAnexadoSolicitacaoBLL docsBLL = new DocumentoAnexadoSolicitacaoBLL();
                    TipoAlteracaoBLL tipAltBLL = new TipoAlteracaoBLL();

                    var justificativaArmazenada = Session["TxtJustificativa"] as string;
                    s.Usuario = usuario.Nomusu;
                    s.DatCriacao = DateTime.Now;
                    s.TxtJustificativa = !String.IsNullOrEmpty(s.TxtJustificativa) ?
                        s.TxtJustificativa
                        : !String.IsNullOrEmpty(justificativaArmazenada) ? justificativaArmazenada : "";

                    // AQUI GERA O TICKET SE AINDA NÃO HOUVER DADOS DA SOLICITAÇÃO -> OK
                    if (dps.CodigoDadoPrincipal == 0)
                    {

                        //------------------------------------------------------------------------
                        if (s.CodCliente == 0)
                        {
                            s.CodTipoSolicitacao = Convert.ToInt32(TipoSolicitacao.Inclusao);
                        }
                        else // se o código do cliente não for 0, pode ser duplicação ou alteração.
                        {
                            if (s.CodTipoSolicitacao != 3) // se vem da duplicação, o codTipoSolicitacao foi definido lá
                            {
                                s.CodTipoSolicitacao = Convert.ToInt32(TipoSolicitacao.Alteracao);
                            }
                        }
                        //------------------------------------------------------------------------

                        #region Salvar o histórico da solicitação se não existir ( MOSTROU-SE DESNECESSÁRIO )

                        //var historico = s.Historicos.LastOrDefault();
                        //if (historico == null)
                        //{
                        //    // Inserir como 'DIGITANDO' (código 1)
                        //    var h = new HistoricoSolicitacao();
                        //    h.CodSituacaoSolicitacao = Convert.ToInt32(SituacaoSolicitacao.AguardandoFechamento);
                        //    s.CodSituacaoAtual = Convert.ToInt32(SituacaoSolicitacao.AguardandoFechamento);
                        //    h.Solicitacao = s;
                        //    s.Historicos.Add(h);
                        //}
                        #endregion
                        s.CodSituacaoAtual = Convert.ToInt32(SituacaoSolicitacao.AguardandoFechamento);
                        solicitacaoBLL.SalvarOuAtualizar(s);

                        if (tiposDeAlteracao != null)
                        {
                            foreach (var t in tiposDeAlteracao)
                            {
                                var codTipoAlteracao = Convert.ToInt32(t);
                                var tipo = tipAltBLL.ObterPorCodigo(codTipoAlteracao);

                                if (!s.TiposAlteracao.Contains(tipo))
                                {

                                    s.TiposAlteracao.Add(tipo);
                                }

                                //se o tipo de alteração que eu estou tentando gravar já existir, não gravar.

                            }
                        }
                        solicitacaoBLL.Atualizar(s);

                        dps.Solicitacao = s; // atribui a chave estrageira (solicitação) ao dado principal.

                        dps.EmailNFE = String.IsNullOrEmpty(dps.EmailNFE) ? "" : dps.EmailNFE;// +";" + dps.EmailNFE2;

                        dadoPrincipalBLL.Salvar(dps); // salva os dados principais.
                    }
                    else
                    {
                        var dadoPrincipal = dadoPrincipalBLL.ObterPorCodigo(dps.CodigoDadoPrincipal);

                        dadoPrincipal.Ativo = dps.Ativo;
                        dadoPrincipal.Bairro = dps.Bairro;
                        dadoPrincipal.CEP = dps.CEP;
                        dadoPrincipal.Cidade = dps.Cidade;
                        dadoPrincipal.CobraCliente = dps.CobraCliente;
                        dadoPrincipal.CodClienteDadoPrincipalSol = dps.CodClienteDadoPrincipalSol;
                        dadoPrincipal.CodGrupoEmpresa = dps.CodGrupoEmpresa;
                        dadoPrincipal.CodIBGE = dps.CodIBGE;
                        dadoPrincipal.CodigoDadoPrincipal = dps.CodigoDadoPrincipal;
                        dadoPrincipal.CodRamoAtividade = dps.CodRamoAtividade;
                        dadoPrincipal.CodRota = dps.CodRota;
                        dadoPrincipal.CodSubRota = dps.CodSubRota;
                        dadoPrincipal.Complemento = dps.Complemento;
                        dadoPrincipal.ContribuinteICMS = dps.ContribuinteICMS;
                        dadoPrincipal.CPFCNPJ = dps.CPFCNPJ;
                        dadoPrincipal.DataUltimaConsulta = dps.DataUltimaConsulta;
                        dadoPrincipal.EmailNFE2 = dps.EmailNFE2;
                        dadoPrincipal.EmailNFE = dps.EmailNFE + ";" + dps.EmailNFE2;
                        dadoPrincipal.ExpurgaDaInadimplencia = dps.ExpurgaDaInadimplencia;
                        dadoPrincipal.InscricaoEstadual = dps.InscricaoEstadual;
                        dadoPrincipal.Isento = dps.Isento;
                        dadoPrincipal.Logradouro = dps.Logradouro;
                        dadoPrincipal.NomeFantasia = dps.NomeFantasia;
                        dadoPrincipal.Numero = dps.Numero;
                        dadoPrincipal.NumeroFax = dps.NumeroFax;
                        dadoPrincipal.ObservacaoMotivoSituacao = dps.ObservacaoMotivoSituacao;
                        dadoPrincipal.PontoDeReferencia = dps.PontoDeReferencia;
                        dadoPrincipal.RamoFiscal = dps.RamoFiscal;
                        dadoPrincipal.RazaoSocial = dps.RazaoSocial;
                        dadoPrincipal.SituacaoReceitaFederal = String.IsNullOrEmpty(dadoPrincipal.SituacaoReceitaFederal) ? "Consulta não retornou dados" : dadoPrincipal.SituacaoReceitaFederal;
                        dadoPrincipal.SituacaoReceitaEstadual = String.IsNullOrEmpty(dadoPrincipal.SituacaoReceitaEstadual) ? "Consulta não retornou dados" : dadoPrincipal.SituacaoReceitaEstadual;
                        dadoPrincipal.Solicitacao = s;
                        dadoPrincipal.Telefone = dps.Telefone;
                        dadoPrincipal.Telefone2 = dps.Telefone2;
                        dadoPrincipal.Telefone3 = dps.Telefone3;
                        dadoPrincipal.Telefone4 = dps.Telefone4;
                        dadoPrincipal.Telefone5 = dps.Telefone5;
                        dadoPrincipal.TipoCliente = dps.TipoCliente;
                        dadoPrincipal.TipoDireitoPropriedadeEmpresa = dps.TipoDireitoPropriedadeEmpresa;
                        dadoPrincipal.TipoEmpresa = dps.TipoEmpresa;
                        dadoPrincipal.TipoMercado = dps.TipoMercado;
                        dadoPrincipal.TributaICMS = dps.TributaICMS;
                        dadoPrincipal.UF = dps.UF;

                        solicitacaoBLL.SalvarOuAtualizar(s);// AQUI GERA O TICKET     -> OK

                        /////////////////////
                        if (tiposDeAlteracao != null)
                        {
                            foreach (var t in tiposDeAlteracao)
                            {
                                var codTipoAlteracao = Convert.ToInt32(t);
                                var tipo = tipAltBLL.ObterPorCodigo(codTipoAlteracao);

                                if (!s.TiposAlteracao.Contains(tipo))
                                {
                                    s.TiposAlteracao.Add(tipo);
                                }
                            }
                            solicitacaoBLL.Atualizar(s);
                        }
                        /////////////////////

                        dps.Solicitacao = s;
                        dadoPrincipalBLL.Atualizar(dadoPrincipal);
                    }

                    s.DadosPrincipaisSolicitacao.Clear();
                    s.DadosPrincipaisSolicitacao.Add(dps); // as vezes reclama de session aberta, solução -> trazer do banco , preencher os dados e atualizar.

                }

                Session["Solicitacao"] = s;
                new SolicitacaoBLL().ObterNomes(new List<Solicitacao>() { s });
                return Json(new { msg = "Dados Principais gravados com sucesso. ticket nº: " + s.Codigo, codSol = s.Codigo, datCriacao = s.DatCriacao.ToShortDateString(), filial = s.Filial, status = s.Situacao, tipo = s.Tipo }, JsonRequestBehavior.DenyGet);
            }
            catch (Exception ex)
            {
                return Json(new { msg = "Erro ao tentar gravar dados principais: " + ex.Message }, JsonRequestBehavior.DenyGet);
            }
        }
        public ActionResult Reabrir(int codigo)
        {
            //Autentica
            if (Session["ConexaoSapiens"] == null)
            {
                return RedirectToAction("Login", "Home");
            }

            //Autoriza
            if (!AutorizaUsuario(Helpers.ControlAccessConfig.NovaSolicitacao))
            {
                return View("Erro", null, "Módulo não autorizado para este usuário. ");
            }

            using (var hisBLL = new HistoricoSolicitacaoBLL())
            {
                var solBLL = new SolicitacaoBLL();
                var s = solBLL.ObterPorCodigo(codigo);

                if (s == null)
                {
                    return View("Erro");
                }

                var aguardandoFechamento = Convert.ToInt32(SituacaoSolicitacao.AguardandoFechamento);
                var historico = new HistoricoSolicitacao();
                historico.CodSituacaoSolicitacao = aguardandoFechamento;

                s.CodSituacaoAtual = aguardandoFechamento;

                solBLL.Atualizar(s);
                historico.DatEncaminhamento = DateTime.Now;
                historico.Solicitacao = s;
                hisBLL.Salvar(historico);

            }
            // inserir um novo histórico para a solicitação passada, com o código de situação = 1

            return RedirectToAction("Index", "Solicitacao");
        }
        //sem suporte nativo no 2010, instalar o ASync CTP e testar futuramente...
        //      public async Task DoWork()
        //      {
        //          int[] ids = new[] { 1, 2, 3, 4, 5 };
        //          await Task.WhenAll(ids.Select(i => DoSomething(1, i, blogClient)));
        //      }
        /// <summary>
        /// Aprova várias solicitações usando paralelismo (uso de vários núcleos da CPU disponível)
        /// </summary>
        /// <param name="solicitacoes">uma lista dos códigos das solicitações a aprovar, passados como uma string.</param>
        /// <returns></returns>
        public ActionResult AprovarVarias(string solicitacoes)
        {
            try
            {
                //Autentica
                if (Session["ConexaoSapiens"] == null)
                {
                    return RedirectToAction("Login", "Home");
                }

                //Autoriza
                if (!AutorizaUsuario(ControlAccessConfig.ListaAnalise))
                {
                    return View("Erro", null, "Módulo não autorizado para este usuário. ");
                }
                // verificar se é usuário master
                var perfilBLL = new PerfilUsuarioBLL();

                var usuario = (UsuarioSapiens)Session["ConexaoSapiens"];

                usuario.PerfisUsuario = perfilBLL.ObterGruposPorCodUsuario(usuario.Codusu);

                var queryMaster = from perfil in usuario.PerfisUsuario
                                  where perfil.CodPerfilUsuario == 8
                                  select perfil;

                var isUsuarioMaster = queryMaster.ToList().Count > 0;

                if (isUsuarioMaster)
                {
                    // array [1,2,3,4] veio na request como uma string 1,2,3,4, separar e criar um array de inteiros.
                    var codigos = solicitacoes.Split(',').Select(x => Int32.Parse(x)).ToArray();

                    List<int> aprovados = new List<int>();

                    using (ParecerSolicitacaoBLL parecerBLL = new ParecerSolicitacaoBLL())
                    {

                        var historicoBLL = new HistoricoSolicitacaoBLL();

                        foreach (var c in codigos)
                        {
                            // aprovar várias...
                            // pegar o último parecer de cada solicitação.

                            Thread t = new Thread(_ =>
                            {
                                ServiceReferenceTeste.srvSicadSoapClient clienteTesteIntegracao = new ServiceReferenceTeste.srvSicadSoapClient();
                                clienteTesteIntegracao.IntegrarDadosCliente(c);
                            });

                            t.Start();

                            aprovados.Add(c);

                            //var parecer = solBLL.ObterPorCodigo(c).PareceresSolicitacao.Last();

                            // parecer.Codsitpar = Convert.ToDecimal(SituacaoParecer.AguardandoIntegracao);
                            // parecerBLL.Atualizar(parecer);
                            var historico = new HistoricoSolicitacao();
                            historico.DatEncaminhamento = DateTime.Now;
                            historico.CodSituacaoIntegracaoSolicitacao = Convert.ToInt32(SituacaoIntegracaoSolicitacao.Integrado);
                            historico.CodSituacaoSolicitacao = Convert.ToInt32(SituacaoSolicitacao.Integrada);
                            var s = new SolicitacaoBLL().ObterPorCodigo(c);
                            historico.Solicitacao = s;

                            historicoBLL.Salvar(historico);
                        }
                    }
                    // atualizar o grid na tela..
                    return Json(new { aprovados = aprovados }, JsonRequestBehavior.DenyGet);
                }
                else
                {
                    return Json(new { erro = "A Função \"Aprovar Selecionados\" não está disponível para o usuário atual. " }, JsonRequestBehavior.DenyGet);
                }
            }
            catch (Exception ex)
            {
                return Json(new { erro = ex.Message }, JsonRequestBehavior.DenyGet);
            }
        }
        public ActionResult SalvarParecer(DadoPrincipalAprovacao dadPri, DefinicoesClienteAprovacao defCli, string Txtpar, string StatusParecer, string chkEncerra, string vlrLimAnalise, string cpgAnalise, string fpgAnalise)
        {
            using (ParecerSolicitacaoBLL parecerSolicitacaoBLL = new ParecerSolicitacaoBLL())
            {
                PerfilUsuarioBLL perfilBLL = new PerfilUsuarioBLL();
                ConfiguracaoWorkflowBLL configBLL = new ConfiguracaoWorkflowBLL();
                HistoricoSolicitacaoBLL historicoBLL = new HistoricoSolicitacaoBLL();

                ParecerSolicitacao p = Session["Parecer"] as ParecerSolicitacao;
                Solicitacao s = Session["Solicitacao"] as Solicitacao;

                var historico = new HistoricoSolicitacao();

                var usuario = Session["ConexaoSapiens"] as UsuarioSapiens;
                List<PerfilUsuario> perfisUsuarioLogado = null;

                if (usuario != null)
                {
                    perfisUsuarioLogado = perfilBLL.ObterGruposPorCodUsuario(usuario.Codusu);
                }

                // se algum dos perfis do usuário logado contém o perfil aprovador, pode salvar parecer.
                var queryPodeSalvarParecer = from meuPerfil in perfisUsuarioLogado
                                             where meuPerfil.CodPerfilUsuario == p.Codperusu
                                             select meuPerfil;

                var podeSalvar = queryPodeSalvarParecer.Count() > 0 ? true : false;

                // Se o usuário logado não tiver o perfil de aprovação, não pode salvar o parecer
                if (!podeSalvar)
                {
                    return Json(new { msg = "O perfil atual não tem permissão para aprovar este parecer." }, JsonRequestBehavior.DenyGet);
                }

                switch (StatusParecer)
                {
                    case "AP":
                        p.Codsitpar = Convert.ToDecimal(SituacaoParecer.Aprovada);
                        break;

                    case "RP":
                        p.Codsitpar = Convert.ToDecimal(SituacaoParecer.Reprovada);
                        p.Solicitacao.Situacao = "REPROVADA";
                        historico.CodSituacaoSolicitacao = Convert.ToInt32(SituacaoParecer.Reprovada);
                        historico.DatFinalizacao = DateTime.Now;

                        break;
                }

                #region atualiza o parecer atual com os dados que estão na tela.

                SalvarDadoPrincipal(dadPri);

                defCli.VlrLimite = vlrLimAnalise;
                defCli.CodCondicaoPagamento = cpgAnalise;
                defCli.CodFormaDePagamento = fpgAnalise;

                SalvarDefinicoes(defCli);

                #endregion

                // usando o SignalR para implementar atualização geral em tempo real.
                // (atualiza os grids de todos os usuários logados , sem necessidade do F5)
                var context = GlobalHost.ConnectionManager.GetHubContext<StatusHub>();

                //o parecer persistido ( pode gravar, atualizar, até excluir pelo BLL);
                var parecer = parecerSolicitacaoBLL.ObterPorCodigo(p.CodParecer);

                parecer.Codsitpar = p.Codsitpar; // O Novo parecer inicia como Aguardando Aprovação.
                parecer.Codusuapr = usuario.Codusu;
                parecer.Datpar = DateTime.Now;
                parecer.Solicitacao = p.Solicitacao;
                parecer.Txtpar = Txtpar;

                try
                {
                    if (!String.IsNullOrEmpty(Txtpar))
                    {
                        // se entrar aqui , está APROVADA e OK para Gravar.
                        if (parecer.Codsitpar == Convert.ToDecimal(SituacaoParecer.Aprovada))
                        {
                            // verificar na configuração de alçada se tem próximo nível e qual é esse nível.
                            // 21/08/2015 - verificar se o parecer que está sendo aprovado é o último necessário

                            // se o usuário aprovador corresponde ao nivel máximo, ou se está marcado para encerrar o parecer, pode enviar...
                            var prontaParaIntegrar = (((parecer.Codperusu - 2) == s.nivelMaximo) || chkEncerra == "S");
                            //(s.PareceresSolicitacao.Count - 1) == s.nivelMaximo || chkEncerra == "S"
                            if (prontaParaIntegrar)
                            {
                                try
                                {
                                    // muda status para Aguardando integração
                                    parecer.Codsitpar = Convert.ToDecimal(SituacaoParecer.AguardandoIntegracao);
                                    parecer.Solicitacao.CodSituacaoAtual = Convert.ToInt32(SituacaoSolicitacao.AguardandoIntegracao);
                                    parecerSolicitacaoBLL.Atualizar(parecer);

                                    s.CodSituacaoAtual = Convert.ToInt32(SituacaoSolicitacao.AguardandoIntegracao);

                                    Thread t = new Thread(_ =>
                                    {
                                        ServiceReferenceTeste.srvSicadSoapClient clienteTesteIntegracao = new ServiceReferenceTeste.srvSicadSoapClient();
                                        clienteTesteIntegracao.IntegrarDadosCliente(p.Solicitacao.Codigo);
                                    });

                                    t.Start();

                                    historico.DatEncaminhamento = DateTime.Now;
                                    historico.CodSituacaoSolicitacao = Convert.ToInt32(SituacaoSolicitacao.AguardandoIntegracao);
                                    historico.Solicitacao = s;
                                    if (chkEncerra == "S")
                                    {
                                        Txtpar += " ( Encerramento do workflow antecipado por " + usuario.Nomusu + " )";
                                    }
                                    historico.TxtHistorico = Txtpar;

                                    historicoBLL.Salvar(historico);
                                }
                                catch (Exception ex)
                                {
                                    // TODO: Retirar depois de validar a execução do webservice ( vai ficar aguardando Integração se for finalmente aprovado )
                                    parecer.Codsitpar = Convert.ToDecimal(SituacaoParecer.AguardandoAprovacao);
                                    parecerSolicitacaoBLL.Atualizar(parecer);

                                    throw ex;
                                }
                            }
                            else
                            {

                                int codPerfilAprovadorAtual = Convert.ToInt32(parecer.Codperusu);

                                // se não encerra, cria um novo parecer ...
                                var novoParecer = new ParecerSolicitacao();

                                novoParecer.Solicitacao = p.Solicitacao;

                                novoParecer.Codsitpar = Convert.ToDecimal(SituacaoParecer.AguardandoAprovacao);

                                novoParecer.Codhistsol = historico.CodHistoricoSolicitacao; // pegar o codhist OK
                                //novoParecer.Codperusu = ++p.Codperusu; // o perfil do analista de crédito. -> se o usuário não tiver perfil, avisar na tela.

                                int codPerfilProximoAprovador = 0;

                                switch (codPerfilAprovadorAtual)
                                {
                                    case 2: codPerfilProximoAprovador = 3; break;
                                    case 3: codPerfilProximoAprovador = 4; break;
                                    case 4: codPerfilProximoAprovador = 5; break;

                                    //case 5: return Json("", JsonRequestBehavior.DenyGet);

                                }

                                novoParecer.Codperusu = (decimal)codPerfilProximoAprovador;
                                //novoParecer.Codusuapr = s.CodUsuarioSolicitacao; // obter o codigo do usuario da aprovacao. OK
                                novoParecer.Codusuapr = usuario.Codusu;

                                // necessário definir o código como 0 para instruir o NHibernate que este é um novo objeto.
                                dadPri.CodigoDadoPrincipalAprovacao = 0;
                                dadPri.Parecer = parecer;

                                // salvar todos os dados do parecer anterior no novo parecer, e incluir as alterações feitas na tela.
                                novoParecer.DadosPrincipaisAprovacao.Add(dadPri);

                                defCli.CodDefinicoesClienteAprovacao = 0;
                                defCli.Parecer = parecer;
                                novoParecer.DefinicoesAprovacao.Add(defCli);

                                foreach (var ca in p.CaracteristicasAprovacao)
                                {
                                    ca.CodCaracteristicaClienteAprovacao = 0;
                                    novoParecer.CaracteristicasAprovacao.Add(ca);
                                }

                                foreach (var ec in p.EnderecosCobrancaAprovacao)
                                {
                                    ec.CodEnderecoCobrancaClienteApr = 0;
                                    novoParecer.EnderecosCobrancaAprovacao.Add(ec);
                                }

                                foreach (var ee in p.EnderecosEntregaAprovacao)
                                {
                                    ee.CodEnderecoEntregaClienteApr = 0;
                                    novoParecer.EnderecosEntregaAprovacao.Add(ee);
                                }

                                foreach (var r in p.ReferenciasAprovacao)
                                {
                                    r.CodReferenciaApr = 0;
                                    novoParecer.ReferenciasAprovacao.Add(r);
                                }

                                foreach (var c in p.ContatosAprovacao)
                                {
                                    c.CodContatoAprovacao = 0;
                                    novoParecer.ContatosAprovacao.Add(c);
                                }

                                foreach (var soc in p.SociosAprovacao)
                                {
                                    soc.CodSocioEmpresaAprovacao = 0;
                                    novoParecer.SociosAprovacao.Add(soc);
                                }

                                foreach (var doc in p.DocumentosAnexadosAprovacao)
                                {
                                    doc.CodDocumentoAnexadoApr = 0;
                                    novoParecer.DocumentosAnexadosAprovacao.Add(doc);
                                }

                                // EX: se estiver R$ 5.000,00 vai ficar 5000, se for nulo vai virar string vazia
                                novoParecer.DefinicoesAprovacao.Last().VlrLimite = String.IsNullOrEmpty(novoParecer.DefinicoesAprovacao.Last().VlrLimite) ? "" : Regex.Replace(novoParecer.DefinicoesAprovacao.Last().VlrLimite, @"(\s+)|(\\+)|(\.+)|(/+)|(\-+)|(\,+)|(R+)|(\$+)", "");
                                novoParecer.DefinicoesAprovacao.Last().VlrLimite = novoParecer.DefinicoesAprovacao.Last().VlrLimite != "" ? novoParecer.DefinicoesAprovacao.Last().VlrLimite.Substring(0, novoParecer.DefinicoesAprovacao.Last().VlrLimite.Length - 2) : "";

                                // EX: se estiver R$ 5.000,00 vai ficar 5000, se for nulo vai virar string vazia
                                novoParecer.DefinicoesAprovacao.Last().VlrDescontoFinanceiro = String.IsNullOrEmpty(novoParecer.DefinicoesAprovacao.Last().VlrDescontoFinanceiro) ? "" : Regex.Replace(novoParecer.DefinicoesAprovacao.Last().VlrDescontoFinanceiro, @"(\s+)|(\\+)|(\.+)|(/+)|(\-+)|(\,+)|(R+)|(\$+)", ""); // .Substring(0, novoParecer.DefinicoesAprovacao.Last().VlrDescontoFinanceiro.Length - 2) estava assim pois inicialmente esse campo foi entendido como monetário, mas é um valor percentual,como em '33%' ou '02%'

                                // salva o novo parecer e os objetos associados.
                                parecerSolicitacaoBLL.Salvar(novoParecer);

                                // atualiza o parecer existente para aprovado
                                parecerSolicitacaoBLL.Atualizar(parecer);

                                historico.Solicitacao = p.Solicitacao;
                                historico.TxtHistorico = p.Txtpar;
                                historico.CodSituacaoSolicitacao = Convert.ToInt32(SituacaoSolicitacao.AguardandoAprovacao);
                                historicoBLL.Salvar(historico);
                            } // fim do "se não encerra"

                        } // fim do "se aprova"
                        else // se não aprova.
                        {
                            historico.DatFinalizacao = DateTime.Now;
                            historico.CodSituacaoSolicitacao = Convert.ToInt32(SituacaoSolicitacao.Reprovada);
                            p.Solicitacao.CodSituacaoAtual = Convert.ToInt32(SituacaoSolicitacao.Reprovada);
                            s.CodSituacaoAtual = Convert.ToInt32(SituacaoSolicitacao.Reprovada);
                            historico.Solicitacao = p.Solicitacao;
                            historico.TxtHistorico = Txtpar; // MOTIVO DA REPROVAÇÃO.
                            historicoBLL.SalvarOuAtualizar(historico);

                            //TODO: atualizar o código da situação da solicitação.
                            new SolicitacaoBLL().AtualizarSituacao(s.Codigo, Convert.ToInt32(SituacaoSolicitacao.Reprovada));

                            parecerSolicitacaoBLL.Atualizar(parecer);

                            context.Clients.All.AtualizarGrid();
                            return Json(new { msg = "Parecer Atualizado." }, JsonRequestBehavior.DenyGet);

                        } // fim do "se não aprova"

                        context.Clients.All.AtualizarGrid();
                        return Json(new { msg = "Parecer Atualizado." }, JsonRequestBehavior.DenyGet);
                    }
                    else
                    {
                        throw new Exception("Não foi possível obter o texto do parecer.");
                    }
                } // Fim do try

                catch (Exception ex)
                {
                    historico.Solicitacao = p.Solicitacao;
                    historico.CodSituacaoIntegracaoSolicitacao = Convert.ToInt32(SituacaoIntegracaoSolicitacao.Erro);
                    historico.CodSituacaoSolicitacao = Convert.ToInt32(SituacaoSolicitacao.AguardandoAprovacao);
                    historico.TxtHistorico = ex.Message;
                    historico.DatFinalizacao = DateTime.Now;
                    historicoBLL.Salvar(historico);

                    return Json(new { erro = "Não foi possível salvar o parecer. Detalhes : " + ex.Message }, JsonRequestBehavior.DenyGet);
                }
            }
        }
        public ActionResult Reintegrar(int codigo)
        {
            try
            {
                //Autentica
                if (Session["ConexaoSapiens"] == null)
                {
                    return RedirectToAction("Login", "Home");
                }

                //Autoriza
                if (!AutorizaUsuario(ControlAccessConfig.ListaAnalise))
                {
                    return View("Erro", null, "Módulo não autorizado para este usuário. ");
                }
                // verificar se é usuário master
                var perfilBLL = new PerfilUsuarioBLL();

                var usuario = (UsuarioSapiens)Session["ConexaoSapiens"];

                usuario.PerfisUsuario = perfilBLL.ObterGruposPorCodUsuario(usuario.Codusu);

                var queryTi = from perfil in usuario.PerfisUsuario
                              where perfil.CodPerfilUsuario == 1
                              select perfil;

                var ehUsuarioTI = queryTi.ToList().Count > 0;

                if (ehUsuarioTI)
                {
                    using (ParecerSolicitacaoBLL parecerBLL = new ParecerSolicitacaoBLL())
                    {

                        var historicoBLL = new HistoricoSolicitacaoBLL();

                        Thread t = new Thread(_ =>
                        {
                            ServiceReferenceTeste.srvSicadSoapClient clienteTesteIntegracao = new ServiceReferenceTeste.srvSicadSoapClient();
                            clienteTesteIntegracao.IntegrarDadosCliente(codigo);
                        });

                        t.Start();

                        // pegar o último parecer da solicitação.

                        // var parecer = solBLL.ObterPorCodigo(c).PareceresSolicitacao.Last();

                        // parecer.Codsitpar = Convert.ToDecimal(SituacaoParecer.AguardandoIntegracao);
                        // parecerBLL.Atualizar(parecer);

                        var historico = new HistoricoSolicitacao();
                        historico.DatEncaminhamento = DateTime.Now;
                        historico.CodSituacaoIntegracaoSolicitacao = Convert.ToInt32(SituacaoIntegracaoSolicitacao.Pendente);
                        historico.CodSituacaoSolicitacao = Convert.ToInt32(SituacaoSolicitacao.Aprovada);
                        var s = new SolicitacaoBLL().ObterPorCodigo(codigo);
                        historico.Solicitacao = s;
                        historico.TxtHistorico = "Nova tentativa de reintegração.";

                        historicoBLL.Salvar(historico);
                    } // fim do using

                    // atualizar o grid na tela..
                    return Json(new { msg = "Integração iniciada..." + codigo }, JsonRequestBehavior.AllowGet);
                }
                else
                {
                    return Json(new { erro = "A Função \"Reintegrar\" não está disponível para o usuário atual. " }, JsonRequestBehavior.AllowGet);
                }
            }
            catch (Exception ex)
            {
                return Json(new { erro = ex.Message }, JsonRequestBehavior.DenyGet);
            }
        }