✏️ 正在编辑: Api.php
路径:
/srv/systems_dir/yuppiecred-lidernegocios/library/Core/Banco/Service/Safra/Api.php
提示:
您可以编辑任何文件(包括二进制文件),但请注意不当修改可能导致文件损坏。
<?php class Core_Banco_Service_Safra_Api extends Core_Banco_Service_Autocontratacao_Fgts implements Core_Banco_Service_ImportacaoDireta { protected $_url = 'https://api.safrafinanceira.com.br/apl-api-correspondente/api/v1'; protected $_indiceUsuario = 0; protected $_dadosUsuarios = null; protected $_usuarioId = null; protected $_usuario = null; protected $_senha = null; protected $_authorization = null; private $_bancoId = null; private $_loginCertificado = null; private $_origemConsulta = null; private $_tabelasJuros = null; private $_erros = null; private $_naoImportados = []; public function getBancoId() { return $this->_bancoId; } public function getOrigemConsulta() { return $this->_origemConsulta; } public function __construct() { $this->_bancoId = Model_Banco::bancoPorNome('SAFRA'); if (empty($this->_bancoId)) { throw new Core_Exception("Banco Safra não está cadastrado."); } $application = service('config')->get()->bancos->safra->api ?? null; if (empty($application)) { $msgErro = 'API do Safra não está configurada.'; throw new Core_Exception($msgErro); } $this->_dadosUsuarios = Model_UsuariosApi::getByApi('SAFRA'); if (count($this->_dadosUsuarios) == 0) { $msgErro = 'Nenhum usuário de API cadastrado.'; throw new Yuppie_Exception($msgErro); } $this->_origemConsulta = 'Safra'; $this->_usuarioId = $this->_dadosUsuarios[$this->_indiceUsuario]['id']; $this->_usuario = $this->_dadosUsuarios[$this->_indiceUsuario]['usuario']; $this->_senha = $this->_dadosUsuarios[$this->_indiceUsuario]['senha']; $this->_loginCertificado = \String_Refatorar::soNumeros($this->_dadosUsuarios[$this->_indiceUsuario]['login_certificado']); } public function getResponse($urlParam, $params, $auth = false, $post = false, ?array $headersParam = []) { $url = $urlParam; $headers = ["Content-Type: application/json"]; if (!$auth) { $headers[] = "Authorization: Bearer " . $this->_authorization; } $headers = $headers + $headersParam; if (!$post && !empty($params)) { $url = $urlParam . "?" . http_build_query($params); } $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // curl_setopt($curl, CURLOPT_COOKIESESSION, true); curl_setopt($curl, CURLOPT_ENCODING, ''); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_MAXREDIRS, 10); curl_setopt($curl, CURLOPT_TIMEOUT, 0); curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); if ($post) { $params = json_encode($params); curl_setopt($curl,CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($curl, CURLOPT_POSTFIELDS, $params); } else { curl_setopt($curl,CURLOPT_CUSTOMREQUEST, "GET"); } $response = json_decode(curl_exec($curl)); $info = curl_getinfo($curl); curl_close($curl); Yuppie_Log::write("getResponse Service Safra parâmetros enviados para url {$url}:" . print_r($params, true), $this); Yuppie_Log::write("Retorno do getResponse Service Safra:" . print_r($response, true), $this); if (!in_array($info['http_code'], [200, 401])) { $retorno = new stdClass(); $retorno->erros = []; $retorno->erros[0] = new stdClass(); $retorno->erros[0]->code = $info['http_code']; $retorno->erros[0]->descricao = "Falha de comunicação com o Safra"; return $retorno; } elseif ($info['http_code'] == 401 && $this->_countRequest <= 3) { $this->newToken(); return $this->getResponse($urlParam, $params, $auth, $post, $headers); } return $response; } protected function getTokenApi() { //verifica se já tem token gerado $tokenValido = (new Model_DbTable_BancosTokenApi())->checkTokenValido($this->_bancoId, $this->_usuarioId); if (!empty($tokenValido)) { $this->_authorization = $tokenValido['token']; return; } $this->newToken(); } protected function newToken() { $this->_countRequest++; $url = $this->_url . "/Token"; $params = ['username' => $this->_usuario, 'password' => $this->_senha]; $retorno = $this->getResponse($url, $params, true, true); if (!empty($retorno->token)) { $this->_authorization = $retorno->token; $expiraEm = Zend_Date::now()->addMinute($retorno->tokenLifeMinute-2)->get('yyyy-MM-dd HH:mm:ss'); (new Model_DbTable_BancosTokenApi())->saveToken($this->_bancoId, $this->_usuarioId, $this->_authorization, $expiraEm); Model_UsuariosApi::gravarDataUtilizacao($this->_usuarioId); Yuppie_Log::write("Novo token gerado. Expira em: " . $expiraEm, $this); return; } if ($this->setProximoUsuario(true)) { return $this->newToken(); } } protected function setProximoUsuario($erroAutenticacao = false) { if ($erroAutenticacao) { Model_UsuariosApi::desativarUsuario($this->_usuarioId); } $this->_indiceUsuario++; if (!empty($this->_dadosUsuarios[$this->_indiceUsuario]['id'])) { Yuppie_Log::write("Passando para próximo usuário cadastrado.", $this); $this->_usuarioId = $this->_dadosUsuarios[$this->_indiceUsuario]['id']; $this->_usuario = $this->_dadosUsuarios[$this->_indiceUsuario]['usuario']; $this->_senha = $this->_dadosUsuarios[$this->_indiceUsuario]['senha']; $this->_loginCertificado = \String_Refatorar::soNumeros($this->_dadosUsuarios[$this->_indiceUsuario]['login_certificado']); } else { Yuppie_Log::write("Fim dos usuários.", $this); return false; } return true; } public function consultaFgtsCallcenter($cpf) { if (empty($this->_authorization)) { $this->getTokenApi(); } $cpf = String_Refatorar::formatarCpf($cpf); $url = $this->_url . '/Fgts'; $params = ['idCliente' => $cpf]; return $this->getResponse($url, $params); } public function consultaFgts($cpf, $qtdParcelas) { if (empty($this->_authorization)) { $this->getTokenApi(); } $cpf = String_Refatorar::soNumeros($cpf); $url = $this->_url . '/Fgts'; $params = ['idCliente' => $cpf]; $result = $this->getResponse($url, $params); $parcelas = null; if (!$result->periodos) { return $result; } $indice = 0; foreach ($result->periodos as $key => $periodo) { //tratar numero de parcelas escolhidas pelo cliente if ($qtdParcelas > 0 && $qtdParcelas <= $indice) { continue; } $parcelas[$key]['dataRepasse'] = $periodo->dtRepasse; $parcelas[$key]['valorRepasse'] = $periodo->valor; $parcelas[$key]['valorFinanciado'] = $periodo->valor; $indice++; } return $this->calcularSimulacao($parcelas, false, $cpf); } protected function calcularSimulacao($periodos, $inclusao = false, $cpf) { $this->getTabelaJuros(); // Separando parcelas por tabela pra realizar a consulta do calculo $cpf = String_Refatorar::soNumeros($cpf); $url = $this->_url.'/Calculo/FGTS'; $calculo = null; if (count($this->_tabelasJuros) == 0) { $retorno = new stdClass(); $retorno->erros = []; $retorno->erros[0] = new stdClass(); $retorno->erros[0]->code = 0; $retorno->erros[0]->descricao = "Nenhuma tabela localizada para realizar simulação."; return $retorno; } foreach ($this->_tabelasJuros as $tabelaJuros) { $params = [ 'periodos' => $periodos, 'idTabelaJuros' => $tabelaJuros->codigo, 'idCliente' => $cpf ]; $calculo = $this->getResponse($url, $params, false, true); if (!empty(current($calculo->simulacoes))) { break; } } if ($inclusao) { return [ 'parcelas1' => $periodos, 'calculo1' => [ 'prazo' => current($calculo->simulacoes)->prazo, 'valor_liquido' => current($calculo->simulacoes)->valorPrincipal, 'valor_bruto' => current($calculo->simulacoes)->valorFinanciado, ] ]; } return $this->formatarRetornoFGTS($calculo, $periodos); } public function formatarRetornoFGTS($retorno, $periodos) { if (empty($retorno)) { throw new Core_Exception("Nenhuma informação retornada pelo banco Safra"); } $parcelas = []; $dt = new Zend_Date(); foreach ($periodos as $key => $periodo) { $parcelas[$key]['num_parcela'] = $key + 1; $parcelas[$key]['valor_parcela'] = $periodo['valorRepasse']; $parcelas[$key]['data_vencimento'] = $dt->set($periodo['dataRepasse'])->toString('dd/MM/yyyy'); } $simulacoes = current($retorno->simulacoes); $data = new stdClass(); $data->condicoes_credito = []; $tabela = $this->_tabelasJuros; $calculos = [ 'codigo_tabela_financiamento' => $tabela->id, 'descricao_tabela_financiamento' => $tabela->descricao, 'codigo_produto' => $tabela->id, 'produto' => $tabela->descricao, 'descricao_produto' => $tabela->descricao, 'valor_bruto' => $simulacoes->valorFinanciado, 'valor_liquido' => $simulacoes->valorPrincipal, 'valor_financiado' => $simulacoes->valorFinanciado, 'saldo_total' => $simulacoes->valorFinanciado, 'taxa_referencia_mensal' => $simulacoes->taxaJuros, 'prazo' => $simulacoes->prazo, 'valor_parcela' => $simulacoes->valorParcela ]; $data->condicoes_credito[0] = (object) array_merge(['parcelas' => $parcelas], $calculos); $data->origem_consulta = $this->getOrigemConsulta(); return $data; } public function inclusaoFgts($dados, $condicoesCredito, $propostaId) { if (empty($this->_authorization)) { $this->getTokenApi(); } $calculos = $this->prepararParcelas($condicoesCredito['parcelas'], $dados['cpf']); $condicoesCredito['parcelas'] = $calculos['parcelas1']; $condicoesCredito['tabelaJuros'] = $this->_tabelasJuros->id; $this->atualizarCondicoesCredito($condicoesCredito, $calculos['calculo1'], $propostaId); $params = $this->montarParamsFgtsInclusao($dados, $condicoesCredito); $url = $this->_url . "/Propostas/Fgts"; $response = $this->getResponse($url, $params, false, true); if (empty($response->idProposta)) { if ($this->setProximoUsuario()) { $this->newToken(); return $this->inclusaoFgts($dados, $condicoesCredito, $propostaId); } return $response; } $data = new stdClass(); $data->retorno->numero_proposta = $response->idProposta; return $data; } public function prepararParcelas($parcelas, $cpf) { $periodos = null; $dt = new Zend_Date(); foreach ($parcelas as $key => $periodo) { $periodos[$key]['dataRepasse'] = $dt->set($periodo['data_vencimento'])->toString('yyyy-MM-ddThh:mm:ss'); $periodos[$key]['valorRepasse'] = $periodo['valor_parcela']; $periodos[$key]['valorFinanciado'] = $periodo['valor_parcela']; } return $this->calcularSimulacao($periodos, true, $cpf); } public function atualizarCondicoesCredito(&$condicoesCredito, $dadosUpdate, $propostaId = null) { if ($propostaId) { $tbProposta = new Model_DbTable_Proposta(); $tbProposta->update($dadosUpdate, ['id = ?' => $propostaId]); } $condicoesCredito->valor_financiado = $dadosUpdate['valor_bruto']; $condicoesCredito->valor_liquido = $dadosUpdate['valor_liquido']; $condicoesCredito->prazo = $dadosUpdate['prazo']; } public function montarParamsFgtsInclusao($dados, $condicoesCredito): array { $periodos = []; $dt = new Zend_Date(); foreach ($condicoesCredito['parcelas'] as $condicao) { $periodos[] = [ "dtRepasse" => $dt->set($condicao['dataRepasse'])->toString('yyyy-MM-ddThh:mm:ss.000Z'), "valorReservado" => $condicao['valorRepasse'], "valortotal" => $condicao['valorFinanciado'], ]; } try { $dataNascimento = new Zend_Date($dados['data_nascimento']); } catch (Zend_Date_Exception $e) { throw new Core_Exception("Data de nascimento ({$dados['data_nascimento']}) é inválida."); } $fone = trim(String_Refatorar::soNumeros($dados['fone'])); $params = [ 'dadosProposta' => [ 'periodos' => $periodos, 'idConvenio' => 50057, //FGTS 'idTabelaJuros' => $condicoesCredito['tabelaJuros'], 'valorPrincipal' => $condicoesCredito['valor_liquido'], 'valorParcela' => $condicoesCredito['valor_parcela'], 'prazo' => $condicoesCredito['prazo'], 'idUF' => $dados['uf'], 'comSeguro' => false, 'cpfAgenteCertificado' => (int)$this->_loginCertificado, 'tipoFormalizacao' => 10, // "idProposta" => 0, // "tpProduto" => 1 ], 'dadosOcupacao' => [ 'idOrgaoEmpregador' => 3148, //FGTS 'idProfissao' => 340, //340 - Analista 'idCargo' => 3204, //3204 - Analista de gestão de pessoas 'idRegimeJuridico' => 1, //1 = CLT 'idSituacaoEmpregado' => 1, 'idTipoVinculoEmpregaticio' => 2, 'matricula' => String_Refatorar::formatarCpf($dados['cpf']), 'valorRenda' => String_Refatorar::parseStringToFloat($dados['renda_valor']), 'idTipoPagamentoBeneficio' => 0, 'idUFBeneficio' => $dados['uf'], 'dataAdmissao' => "" ], 'dadosPessoais' => [ 'cpf' => String_Refatorar::formatarCpf($dados['cpf']), 'nomeCompleto' => $dados['nome'], 'sexo' => $dados['sexo'], 'dataNascimento' => $dataNascimento->get('yyyy-MM-dd'), 'idEstadoCivil' => 1, 'nomeMae' => $dados['nome_mae'], 'alfabetizado' => $dados['alfabetizado'], 'idUFRG' => $dados['uf_emissao_documento'], 'rg' => $dados['rg'], 'email' => "", 'nomePai' => $dados['nome_pai'], ], 'contatos' => [ [ 'ddd' => substr($fone,0,2), 'telefone' => substr($fone, 2, strlen($fone)), 'email' => "", 'whatsapp' => true ] ], 'endereco' => [ 'cep' => $dados['cep'], 'logradouro' => $dados['endereco'], 'numero' => $dados['numero'], 'bairro' => $dados['bairro'], 'cidade' => $dados['cidade'], 'uf' => $dados['uf'], 'complemento' => $dados['complemento'] ], 'dadosBancarios' => [ 'banco' => $dados['numero_banco'], 'agencia' => $dados['numero_agencia'], 'tipoConta' => in_array($dados['cod_oper_cef'], ["001", "002", "023", "032", "037"]) ? "CC" : "PP", //CC | PP 'conta' => $dados['numero_conta'] ], 'pessoaPoliticamenteExposta' => [ 'isPoliticamenteExposta' => false, 'isPPERelacionado' => false, 'motivo' => "", 'motivoRelacionamento' => "", 'cpf' => "", 'nome' => "" ], 'referenciasPessoais' => [ //o próprio cliente [ 'ddd' => substr($fone,0,2), 'telefone' => substr($fone, 2, strlen($fone)), 'nome' => $dados['nome'], 'idAfinidade' => 9 //cliente ] ], 'dadosBancariosAverbacao' => [ 'bancoAverbacao' => "", 'agenciaAverbacao' => "", 'contaAverbacao' => "" ], 'submeter' => true ]; return $params; } protected function getTabelaJuros() { if (empty($this->_authorization)) { $this->getTokenApi(); } $this->_tabelasJuros = []; $url = $this->_url . "/TabelaJuros/FGTS"; $response = $this->getResponse($url, []); $tabelas = (new Model_Tabela())->getTabelaAutocontratacao('FGTS', $this->getBancoId()); if ($tabelas->count() == 0) { $this->_tabelasJuros[] = current($response); return $this->_tabelasJuros; } $codigosTabelas = array_map(function($value) { return $value->codigo; }, $tabelas->toArray()); foreach ($response as $tabela) { if (in_array($tabela->id, $codigosTabelas)) { $this->_tabelasJuros[] = $tabela; break; } } return $this->_tabelasJuros; } public function tratarMensagemErro(int $clienteId, $retorno) { if (empty($retorno->erros) || empty(current($retorno->erros))) { return; } if (empty(current($retorno->erros)->descricao)) { throw new Core_Exception('Safra: Erro não informado.'); } $mensagem = current($retorno->erros)->descricao; $mensagemRetorno = $this->_erroMessageTreatment($mensagem); if (!empty($mensagemRetorno)) { (new Model_DbTable_CallcenterFgts())->insert([ 'base_id' => $clienteId, 'periodo' => 0, 'data_repasse' => null, 'valor' => 0, 'descricao_erro' => $mensagemRetorno['message'], 'origem_consulta' => "Safra" ]); throw new Core_Exception($mensagemRetorno['message'], $mensagemRetorno['code']); } } public function enviarLinkFormalizacao($numeroContrato, $cpf, $celular) { } public function getUrlFormalizacao($numeroContrato, $cpf) { if (empty($this->_authorization)) { $this->getTokenApi(); } $url = $this->_url . "/Propostas/ObterLinkFormalizacao"; $response = $this->getResponse($url, ['idProposta' => $numeroContrato]); Yuppie_Log::write("Resposta do getUrlFormalizacao: " . print_r($response, true), $this); if (empty($response[0])) { return; } return $response[0]->link ?? ""; } private static function formatData($dataImportacao) { if (empty($dataImportacao)){ $dt = new DateTime(); return $dt->sub(new DateInterval('P1D'))->format('Y-m-d'); } $data = Core_Util::convertDate($dataImportacao, 'd/m/Y'); if( is_array($data) ){ throw new Yuppie_Exception('Data inválida'); } return $data; } private function getContratosEmprestimo(int $numeroContrato) { if (empty($this->_authorization)) { $this->getTokenApi(); } $url = $this->_url . "/ContratosEmprestimo/proposta/" . $numeroContrato; $headers = [ "Accept: text/plain" ]; return $this->getResponse($url, [], false, false, $headers); } private function getContratosDadosCadastrais(int $numeroContrato) { if (empty($this->_authorization)) { $this->getTokenApi(); } $url = $this->_url . "/ContratosDadosCadastrais/proposta/" . $numeroContrato; $headers = [ "Accept: text/plain" ]; return $this->getResponse($url, [], false, false, $headers); } private function getContratosFinanceiro(int $numeroContrato) { if (empty($this->_authorization)) { $this->getTokenApi(); } $url = $this->_url . "/ContratosFinanceiro/proposta/" . $numeroContrato; $headers = [ "Accept: text/plain" ]; return $this->getResponse($url, [], false, false, $headers); } private function getContratosStatus(int $numeroContrato) { if (empty($this->_authorization)) { $this->getTokenApi(); } $url = $this->_url . "/ContratosStatus/proposta/" . $numeroContrato; $headers = [ "Accept: text/plain" ]; return $this->getResponse($url, [], false, false, $headers); } private function getAcompanhamentoFormalizacao(int $numeroContrato) { if (empty($this->_authorization)) { $this->getTokenApi(); } $url = $this->_url . "/AcompanhamentoFormalizacao"; $headers = [ "Accept: text/plain" ]; $params = ['idProposta' => $numeroContrato]; $response = $this->getResponse($url, $params, false, false, $headers); if (!empty($response->erros) && $response->erros[0]->code == 404) { return; } $formalizacao = [ 'tipo_formalizacao' => 0, 'acompanhamento_formalizacao' => null, 'dt_acompanhamento_formalizacao' => null ]; foreach ($response as $item) { $data = $item->dataDescricaoFase; if (stristr($item->descricaoFase, "DIGITAL")) { $formalizacao['tipo_formalizacao'] = 1; } if ($item->dataDescricaoFase > $data) { $data = $item->dataDescricaoFase; $formalizacao['acompanhamento_formalizacao'] = $item->descricaoFase; $formalizacao['dt_acompanhamento_formalizacao'] = $item->dataDescricaoFase; } } return $formalizacao; } public function importar($dataImportacao = null) { $data = self::formatData($dataImportacao); foreach ($this->_dadosUsuarios as $usuario) { if (empty($this->_authorization)) { $this->getTokenApi(); } $url = $this->_url . "/ContratosEmprestimo/data/" . $data; $headers = [ "Accept: text/plain" ]; $contratos = $this->getResponse($url, [], false, false, $headers); if (empty($contratos) || !empty($contratos->status)) { throw new Core_Exception("Nenhum contrato retornado"); } $contratosImportacao = []; foreach ($contratos as $contrato) { if (empty($contrato->nrContrato)) { continue; } $dadosContrato = $this->getContratosDadosCadastrais($contrato->nrContrato); if (empty($dadosContrato) || !empty($dadosContrato->status) || !empty($dadosContrato->erros)) { continue; } $contratosImportacao[$contrato->nrContrato] = array_merge((array)$contrato, (array)$dadosContrato[0]); $dadosFinanceiro = $this->getContratosFinanceiro($contrato->nrContrato); if (!empty($dadosFinanceiro)) { $contratosImportacao[$contrato->nrContrato] = array_merge($contratosImportacao[$contrato->nrContrato], (array)$dadosFinanceiro[0]); } $statusContrato = $this->getContratosStatus($contrato->nrContrato); if (!empty($statusContrato)) { $contratosImportacao[$contrato->nrContrato]['dsStatusContrato'] = $statusContrato[0]->dsStatusContrato; $contratosImportacao[$contrato->nrContrato]['dsSituacaoContrato'] = $statusContrato[0]->dsSituacaoContrato; $contratosImportacao[$contrato->nrContrato]['pendencias'] = $statusContrato[0]->pendencias; } $acompanhamentoFormalizacao = $this->getAcompanhamentoFormalizacao($contrato->nrContrato); if (!empty($acompanhamentoFormalizacao)) { $contratosImportacao[$contrato->nrContrato]['idTpFormalizacao'] = $acompanhamentoFormalizacao['tipo_formalizacao']; $contratosImportacao[$contrato->nrContrato]['obs'] = !empty($acompanhamentoFormalizacao['dt_acompanhamento_formalizacao']) ? $acompanhamentoFormalizacao['dt_acompanhamento_formalizacao'] . " - " . $acompanhamentoFormalizacao['acompanhamento_formalizacao'] : NULL; } } $planilha = new Core_Banco_Service_Safra_WebService($this->_bancoId, null); $arquivo = new stdClass(); $arquivo->arquivo = "IMPORTACAO_API_SAFRA"; $planilha->setArquivoOrigem($arquivo); $result = $planilha->importar($contratosImportacao); $this->_naoImportados = array_merge($this->_naoImportados, $result); if (!$this->setProximoUsuario()) { return $this->_naoImportados; } } return $this->_naoImportados; } public function getErros() { return $this->_erros; } }
💾 保存文件
← 返回文件管理器