Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá galera, tudo bem?
Me ajudem com essa lógica?
Estou fazendo a leitura do arquivo retorno do banco (cnab400), como alguns sabem, ele é um arquivo texto onde contem dados sobre os pagamentos recebidos pelo banco.
Nesse arquivo, já fiz a estrutura para ler todos os dados e estes já estão em variáveis, tudo certinho, e nestas variáveis existe uma que é o "Nosso numero", que nada mais é do que o ID do meu cliente me meu banco de dados. Porém, preciso fazer uma rotina que verifica se este id existe no banco de dados para depois fazer o update na tabela e os que não existirem retornar em uma query!
Por exemplo:
Este arquivo vem com 100 linhas de dados. Primeiramente ele tem que comparar todos que existem, dar baixa no DB e para aqueles que não existirem no DB ele me retorna uma query com os dados que não encontrou.
Hoje, minha estrutura de leitura está assim:
function linhaProcessada($self, $numLn, $vlinha) {
if($vlinha) {
if($vlinha["registro"] == $self::DETALHE) {
$nossonumero = $vlinha['nosso_numero'];
$datapagamento = $vlinha["data_ocorrencia"];
$valorpago = $vlinha["valor_recebido"];
$valorpago2=number_format ($valorpago, 2, ',', '.');
$valorpago3=number_format ($valorpago, 2, '.', ',');
$iid = $nossonumero;
$conn = mysql_connect("localhost", "teste", "123456") or die ('Não foi possivel conectar ao banco de dados! Erro: ' . mysql_error());
if ($conn) {mysql_select_db("teste", $conn);}
$sql2 = mysql_query("select i.userid, i.status, i.created as data, i.total as valor, a.name as nome, a.company as unidade
from invoices i
inner join accounts a on (i.userid = a.id)
where i.userid = $nossonumero
group by `duedate`
");
$unidade = mysql_fetch_array($sql2);
$unidade1 =$unidade["unidade"];
$datavenci =$unidade["data"];
$valor_final =$unidade["valor"];
$nome_inquilino = $unidade['nome'];
$new_date = date('Y-m-d', strtotime($datapagamento));
// Atualizando a tabela Invoice
$sqlupdate = mysql_query("UPDATE invoices SET status = 'Paid', total='$valorpago', duedate = '$new_date' WHERE userid = '$nossonumero'");
// Inserindo a transaçao de pagamentos
$sqlinsert = mysql_query("INSERT INTO transactions(ttype, tfrom, tto, amount, date, memo, status) VALUES ('Income', '$nossonumero', '102', '$valorpago', '$new_date', 'Invoice Payment', 'Completed')");
// Adicionando o valor no caixa
$caixa = mysql_query("select balance from accounts WHERE acctype = 'Bank' ");
$account = mysql_fetch_array($caixa);
$balancooriginal =$account["balance"];
$somabalanco = $balancooriginal + $valorpago ;
$bancoupdate = mysql_query("UPDATE accounts SET balance ='$somabalanco'WHERE acctype = 'Bank'");
mysql_close($conn);
?>
<div class="container">
<div class="row-fluid">
<div class="span6">
<div class="widget">
<div class="widget-header">
<div class="title2">
Arquivo Retorno UNICRED ==============> Dados Originais
</div>
</div>
<div class="widget-body">
<div class="tab-widget">
<ul>
<table class="table table-striped mbzero tbl-mail">
<thead>
<tr>
<th width="50%" class="modal-footer">Registro:
<?php echo $nossonumero; ?>
</th>
<th width="50%">
Unidade:
<?php
if ($unidade1 != ''){echo $unidade1;}
else {echo '<span class="alert-danger">Não Cadastrado</span>';}
?>
</th>
<tr>
<th class="modal-footer">Data do pagamento:
<?php echo $new_date; ?>
</th>
<th>Data da Emissão:
<?php echo $datavenci; ?>
</th>
</tr>
<tr>
<th class="modal-footer">Valor Pago:
<?php echo $valorpago2; ?>
</th>
<th>Valor Original:
<?php echo $valor_final; ?></th>
</tr>
</thead>
</table>
</ul>
</div>
</div>
</div>
</div>
<?phpSim, mas além disso eu preciso mostrar depois os arquivos que não foram inseridos/encontrados. Preciso que mostre a qtdade e o nome do "nosso numero"
Gostaria de saber como eu faço o IF neste bolo todo... Porque do jeito que está ai ele está lendo todo o arquivo retorno e inserindo nas tabelas, mesmo se não existir...
Quando você executar um insert no mysql_query, é so usar depois o
http://www.php.net/manual/pt_BR/function.mysql-insert-id.php
que vai recuperar o id para você
Me diz uma coisa..
Como eu uso essa sintaxe no php:
Se existir, execute, senão...
Existe uma outra sintaxe a não ser o if?
Preciso dizer assim:
Se o "nosso numero" existir no DB grave, se não vá para o próximo...Se acabou a leitura deixe uma mensagem.
Desculpe a falta de conhecimento, venho do c++ e estou perdido no php, na verdade estou preso com poucas alternativas de sintaxe que eu conheço.
$sql2 = mysql_query("select i.userid, i.status, i.created as data, i.total as valor, a.name as nome, a.company as unidade
from invoices i
inner join accounts a on (i.userid = a.id)
where i.userid = $nossonumero
group by `duedate`
");
// Verifica se retornou linha, pois execultar o mysql_fetch_array vazio da erro
// Existindo a linha com id no banco de dados faz o update, caso contrario faz o insert
if($sql2){
$unidade = mysql_fetch_array($sql2);
$unidade1 = $unidade["unidade"];
$datavenci = $unidade["data"];
$valor_final = $unidade["valor"];
$nome_inquilino = $unidade['nome'];
$new_date = date('Y-m-d', strtotime($datapagamento));
// Atualizando a tabela Invoice
$sqlupdate = mysql_query("UPDATE invoices SET status = 'Paid', total='$valorpago', duedate = '$new_date' WHERE userid = '$nossonumero'");
} else{
$sqlinsert = mysql_query("INSERT INTO transactions(ttype, tfrom, tto, amount, date, memo, status) VALUES ('Income', '$nossonumero', '102', '$valorpago', '$new_date', 'Invoice Payment', 'Completed')");
}Olha só...
Entendi o que você explicou, mas vou tentar explicar novamente, pois acho que não fui claro..
Vamos lá..
No script abaixo, ele pega os dados importados do arquivo de texto, o banco me envia um numero de controle para eu achar o cliente que pagou no meu banco de dados chamado "nosso numero".
Baseado neste "nosso numero" eu faço uma busca no DB e atualizo 3 tabelas, sendo elas "invoice" (onde vai dar baixa no boleto pago), "Transactions" (onde eu cadastro um novo movimento no caixa) e "accounts" (onde eu adiciono o valor pago no campo bank).
Sendo assim, se o "nosso numero" enviado pelo arquivo de retorno existir no meu DB ele faz toda a atualização nestas 3 tabelas acima, senão ele descarta.
Ai que está o problema, preciso fazer uma rotina em cima deste script que, se existir no DB ele faz as atualizações e no final mostra quais "boletos" foram recebidos (este html já está pronto no script abaixo, porém com as variáveis erradas, pois está pegando todos os valores que veio do arquivo retorno) e quais "boletos" não existem no DB (se acaso a pessoa emitiu segunda via ou por outros meios, por exemplo se ele pagar na internet).
Segue o codigo inteiro desta página:
<?php require ('../manage/views/bmsapp/sections/header.tpl_retorno.php'); ?><?php require_once("RetornoBanco.php");require_once("RetornoFactory.php");function linhaProcessada($self, $numLn, $vlinha) { if($vlinha) { if($vlinha["registro"] == $self::DETALHE) { $nossonumero = $vlinha['nosso_numero']; $datapagamento = $vlinha["data_ocorrencia"]; $valorpago = $vlinha["valor_recebido"]; $valorpago2=number_format ($valorpago, 2, ',', '.'); $valorpago3=number_format ($valorpago, 2, '.', ','); $iid = $nossonumero; $conn = mysql_connect("localhost", "teste", "123456") or die ('Não foi possivel conectar ao banco de dados! Erro: ' . mysql_error()); if ($conn) {mysql_select_db("teste", $conn);} $sql2 = mysql_query("select i.userid, i.status, i.created as data, i.total as valor, a.name as nome, a.company as unidade from invoices i inner join accounts a on (i.userid = a.id) where i.userid = $nossonumero and i.status = 'Unpaid' group by `duedate` "); if (!empty($sql2)) { $unidade = mysql_fetch_array($sql2); $unidade1 =$unidade["unidade"]; $datavenci =$unidade["data"]; $valor_final =$unidade["valor"]; $nome_inquilino = $unidade['nome']; $new_date = date('Y-m-d', strtotime($datapagamento)); // Atualizando a tabela Invoice $sqlupdate = mysql_query("UPDATE invoices SET status = 'Paid', total = '$valorpago', duedate = '$new_date' WHERE userid = '$nossonumero'"); // Inserindo a transaçao de pagamentos $sqlinsert = mysql_query("INSERT INTO transactions (ttype, tfrom, tto, amount, date, memo, status) VALUES ('Income', '$nossonumero', '102', '$valorpago', '$new_date', 'Invoice Payment', 'Completed')"); // Adicionando o valor no caixa $caixa = mysql_query("select balance from accounts WHERE acctype = 'Bank' "); $account = mysql_fetch_array($caixa); $balancooriginal =$account["balance"]; $somabalanco = $balancooriginal + $valorpago ; $bancoupdate = mysql_query("UPDATE accounts SET balance = '$somabalanco' WHERE acctype = 'Bank'"); mysql_close($conn); echo "AQUI TERIA QUE IR UM FORMULARIO MOSTRANDO OS DADOS ATUALIZADOS E OS DADOS NÃO ATUALIZADOS NO DB" ?><?php } else{ echo " Nenhum arquivo conciliado"; } ?><?php } } else echo "Tipo da linha não identificado<br/>\n";}function linhaProcessada1($self, $numLn, $vlinha) { printf("%08d) ", $numLn); if($vlinha) { foreach($vlinha as $nome_indice => $valor) echo get_class($self) . ": $nome_indice: <b>$valor</b><br/>\n "; echo "<br/>\n"; } else echo "Tipo da linha não identificado<br/>\n";}$fileName = $pasta.$nome_atual;//Use uma das duas instrucões abaixo (comente uma e descomente a outra)//$cnab400 = RetornoFactory::getRetorno($fileName, "linhaProcessada1");$cnab400 = RetornoFactory::getRetorno($fileName, "linhaProcessada");$retorno = new RetornoBanco($cnab400);$retorno->processar();?>
.
O que está acontecendo ai também é que mesmo com a condição "where i.userid = $nossonumero and i.status = 'Unpaid'" quando eu refaço a operação ele ainda atualiza todas as outras tabelas menos a Invoice, onde está o Campo Status=Paid, ele não respeita a condição.
Tenho que tentar colocar o: " $sql2 = mysql_query("select i.userid, i.status, i.created as data, i.total as valor, a.name as nome, a.company as unidade from invoices i inner join accounts a on (i.userid = a.id) where i.userid = $nossonumero and i.status = 'Unpaid' group by `duedate` ");" dentro do laço IF, mas se eu fizer isso eu perco o outro laço if (!empty($sql2)) {..}
Alguém?
Thiago você pode trabalhar com substring pra ler o arquivo de retorno, feito isso você consegue saber quais boletos foram pagos, pois ele retorna o nossonumero junto, depois é só utilizar dentro de um for pra atualizar de acordo com esse nosso número, esse é um que utilizo pra ler o arquivo de retorno da Caixa:
<?php
include_once("config.php"); // Arquivo de conexão com o banco de dados
date_default_timezone_set('America/Sao_Paulo');
$nome = $_FILES['arquivo']['name'];
$type = $_FILES['arquivo']['type'];
$size = $_FILES['arquivo']['size'];
$tmp = $_FILES['arquivo']['tmp_name'];
$pasta = "retorno"; //Nome da pasta onde vao ficar armazenados os arquivos;
move_uploaded_file($tmp,$pasta."/".$nome);
$arquivo=file($pasta."/".$nome);
var_dump($arquivo);
foreach($arquivo as $ler){
$linha=$ler;
$t_u_segmento = substr($linha,13,1);//Segmento T ou U
$t_tipo_reg = substr($linha,7,1);//Tipo de Registro
if($t_u_segmento == 'T'){
$t_cod_banco = substr($linha,0,3);//Código do banco na compensação
$t_lote = substr($linha,3,4);//Lote de serviço - Número sequencial para identificar um lote de serviço.
$t_n_sequencial = substr($linha,8,5);//Nr Sequencial do registro no lote
$t_cod_seg = substr($linha,15,2);//Cód. Segmento do registro detalhe
$t_cod_conv_banco = substr($linha,23,6);//Código do convênio no banco - Código fornecido pela CAIXA, através da agência de relacionamento do cliente. Deve ser preenchido com o código do Cedente (6 posições).
$t_n_banco_sac = substr($linha,32,3);//Numero do banco de sacados
$t_mod_nosso_n = substr($linha,39,2);//Modalidade nosso número
$t_id_titulo_banco = substr($linha,41,15);//Identificação do titulo no banco - Número adotado pelo Banco Cedente para identificar o Título.
$t_cod_carteira = substr($linha,57,1);//Código da carteira - Código adotado pela FEBRABAN, para identificar a característica dos títulos. 1=Cobrança Simples, 3=Cobrança Caucionada, 4=Cobrança Descontada
$t_num_doc_cob = substr($linha,58,11);//Número do documento de cobrança - Número utilizado e controlado pelo Cliente, para identificar o título de cobrança.
$t_dt_vencimento = substr($linha,73,8);//Data de vencimento do titulo - Data de vencimento do título de cobrança.
$t_v_nominal = substr($linha,81,13);//Valor nominal do titulo - Valor original do Título. Quando o valor for expresso em moeda corrente, utilizar 2 casas decimais.
$t_cod_banco2 = substr($linha,96,3);//Código do banco
$t_cod_ag_receb = substr($linha,99,5);//Codigo da agencia cobr/receb - Código adotado pelo Banco responsável pela cobrança, para identificar o estabelecimento bancário responsável pela cobrança do título.
$t_dv_ag_receb = substr($linha,104,1);//Dígito verificador da agencia cobr/receb
$t_id_titulo_empresa = substr($linha,105,25);//identificação do título na empresa - Campo destinado para uso da Empresa Cedente para identificação do Título. Informar o Número do Documento - Seu Número.
$t_cod_moeda = substr($linha,130,2);//Código da moeda
$t_tip_inscricao = substr($linha,132,1);//Tipo de inscrição - Código que identifica o tipo de inscrição da Empresa ou Pessoa Física perante uma Instituição governamental: 0=Não informado, 1=CPF, 2=CGC / CNPJ, 9=Outros.
$t_num_inscricao = substr($linha,133,15);//Número de inscrição - Número de inscrição da Empresa (CNPJ) ou Pessoa Física (CPF).
$t_nome = substr($linha,148,40);//Nome - Nome que identifica a entidade, pessoa física ou jurídica, Cedente original do título de cobrança.
$t_v_tarifa_custas = substr($linha,198,15);//Valor da tarifa/custas
$t_id_rejeicoes = substr($linha,213,10);//Identificação para rejeições, tarifas, custas, liquidação e baixas
}
if($t_u_segmento == 'U'){
$t_id_titulo_banco;
$u_cod_banco = substr($linha,0,3);//Código do banco na compensação
$u_lote = substr($linha,3,4);//Lote de serviço - Número sequencial para identificar um lote de serviço.
$u_tipo_reg = substr($linha,7,1);//Tipo de Registro - Código adotado pela FEBRABAN para identificar o tipo de registro: 0=Header de Arquivo, 1=Header de Lote, 3=Detalhe, 5=Trailer de Lote, 9=Trailer de Arquivo.
$u_n_sequencial = substr($linha,8,5);//Nr Sequencial do registro no lote
$u_cod_seg = substr($linha,15,2);//Cód. Segmento do registro detalhe
$u_juros_multa = substr($linha,17,15);//Jurus / Multa / Encargos - Valor dos acréscimos efetuados no título de cobrança, expresso em moeda corrente.
$u_desconto = substr($linha,32,15);//Valor do desconto concedido - Valor dos descontos efetuados no título de cobrança, expresso em moeda corrente.
$u_abatimento = substr($linha,47,15);//Valor do abat. concedido/cancel. - Valor dos abatimentos efetuados ou cancelados no título de cobrança, expresso em moeda corrente.
$u_iof = substr($linha,62,15);//Valor do IOF recolhido - Valor do IOF - Imposto sobre Operações Financeiras - recolhido sobre o Título, expresso em moeda corrente.
$u_v_pago = substr($linha,77,15);//Valor pago pelo sacado - Valor do pagamento efetuado pelo Sacado referente ao título de cobrança, expresso em moeda corrente.
$u_v_liquido = substr($linha,92,15);//Valor liquido a ser creditado - Valor efetivo a ser creditado referente ao Título, expresso em moeda corrente.
$u_v_despesas = substr($linha,107,15);//Valor de outras despesas - Valor de despesas referente a Custas Cartorárias, se houver.
$u_v_creditos = substr($linha,122,15);//Valor de outros creditos - Valor efetivo de créditos referente ao título de cobrança, expresso em moeda corrente.
$u_dt_ocorencia = substr(substr($linha,137,8),4,4).'-'.substr(substr($linha,137,8),2,2).'-'.substr(substr($linha,137,8),0,2);//Data da ocorrência - Data do evento que afeta o estado do título de cobrança.
$u_dt_efetivacao = substr($linha,145,8);//Data da efetivação do credito - Data de efetivação do crédito referente ao pagamento do título de cobrança.
$u_dt_debito = substr($linha,157,8);//Data do débito da tarifa
$u_cod_sacado = substr($linha,167,15);//Código do sacado no banco
$u_cod_banco_comp = substr($linha,210,3);//Cód. Banco Correspondente compens - Código fornecido pelo Banco Central para identificação na Câmara de Compensação, do Banco ao qual será repassada a Cobrança do Título.
$u_nn_banco = substr($linha,213,20);//Nosso Nr banco correspondente - Código fornecido pelo Banco Correspondente para identificação do Título de Cobrança. Deixar branco (Somente para troca de arquivos entre Bancos).
$u_juros_multa = substr($u_juros_multa,0,13).'.'.substr($u_juros_multa,13,2);
$u_desconto = substr($u_desconto,0,13).'.'.substr($u_desconto,13,2);
$u_abatimento = substr($u_abatimento,0,13).'.'.substr($u_abatimento,13,2);
$u_iof = substr($u_iof,0,13).'.'.substr($u_iof,13,2);
$u_v_pago = substr($u_v_pago,0,13).'.'.substr($u_v_pago,13,2);
$u_v_liquido = substr($u_v_liquido,0,13).'.'.substr($u_v_liquido,13,2);
$u_v_despesas = substr($u_v_despesas,0,13).'.'.substr($u_v_despesas,13,2);
$u_v_creditos = substr($u_v_creditos,0,13).'.'.substr($u_v_creditos,13,2);
$data_agora = date('Y-m-d');
$hora_agora = date('H:i:s');
echo "<br /><br />NUMERO DO BOLETO: ".$t_id_titulo_banco."<br />";
echo "MULTA DO BOLETO: ".$u_juros_multa."<br />";
echo "DESCONTO DO BOLETO: ".$u_desconto."<br />";
$taxa = $t_v_tarifa_custas / 100;
$insert = "UPDATE boleto SET valor_pago_fn='$u_v_pago', pagamento_fn='$u_dt_ocorencia', status='P', financ_data_fn='$data_agora', financ_hora_fn='$hora_agora', retorno_fn='$nome',acrescimos='$u_juros_multa',descontos='$u_desconto',taxa='$taxa' WHERE num_boleto='$t_id_titulo_banco'";
echo "RESULTADO SQL: <br />".$insert."<br />";
$query = mysql_query($insert) or die(mysql_error());
}
}
echo"<script type='text/javascript'>";
echo "alert('Arquivo de Retorno Importado com sucesso!');";
echo "history.back();";
echo "</script>";
echo 'Arquivo de Retorno não foi Importado!';
?>Olá Bruno.
Obrigado pela resposta.
O sistema para ler o arquivo retorno está ok, justamente com a substring, tudo redondinho.
O que eu queria é que ele liste após a importação quais arquivos foram atualizados no DB e quais não foram (se esta condição existir).
Seria necessário trabalhar com o for e array, mas eu sou meio perdido no php pois venho do c++ e é tudo diferente.
Eu teria que fazer assim: Ler as linhas do retorno dentro do for (o que já está funcionando) e gravar o dados no db (que já está funcionando) e depois inserir numa outra variável (array), para depois voltar no for e assim por diante, até terminar o laço de repetição, após finalizado eu teria que dar um echo na variavel de array para mostrar todos os dados que foram gravados durante o for... deu pra entender?
Você pode fazer uma variável do tipo array ir recebendo esse valor que precisa. Algo parecido com isso aqui:
$vetor = array();
$vetor[x] = $valor; // Onde x seria a variável do for que vai incrementando
Sugestões,
* antes de fazer qualquer iteração com o banco, trate o arquivo de retorno inteiro e armazene os valores encontrados em um array multidimensional e associativo; armazene-os como se fossem um resultset do banco de dados ou indexe-os pelo número identificador do boleto.
* faça uma consulta no banco para ver quais dos identificadores de boleto encontram-se no array previamente montado (usando IN). Esta consulta será a chave para você fazer o que quer. Com o resultado, é só excluir do array anterior o que não foi encontrado (ou copiar para outro lugar para fazer um diff);
* atualize os registros que restaram no array original, exiba os que não foram encontrados com o diff indicado no parágrafo anterior.
Métodos para estudos envolvidos:
[]'s
Pelo que eu entendi,
é so você fazer um where na tabela que vai buscar os dados,
se vier vazio você insere,
se vier resultado ou seja, existe dados você da um update