✏️ 正在编辑: ArquivoRemessaBradesco.php
路径:
/srv/systems_dir/contemax/library/Core/ArquivoRemessaBradesco.php
提示:
您可以编辑任何文件(包括二进制文件),但请注意不当修改可能导致文件损坏。
<?php class Core_ArquivoRemessaBradesco { const QUEBRA_LINHA = "\r\n"; protected $headerArquivo = array( '01.0' => array( //001 a 001 'digitos' => 1, 'formato' => 'N', 'default' => '0', ), '02.0' => array( //002 a 002 'digitos' => 1, 'formato' => 'N', 'default' => '1', ), '03.0' => array( //003 a 009 'digitos' => 7, 'formato' => 'A', 'default' => 'REMESSA', // Literal Remessa ), '04.0' => array( //010 a 011 'digitos' => 2, 'formato' => 'N', 'default' => '01', ), '05.0' => array( //012 a 026 'digitos' => 15, 'formato' => 'A', 'default' => 'COBRANCA', ), '06.0' => array( //027 a 046 'digitos' => 20, 'formato' => 'N', 'default' => '', ), '07.0' => array( //047 a 076 'digitos' => 30, 'formato' => 'A', 'default' => '', //Razão Social ), '08.0' => array( //077 a 079 'digitos' => 3, 'formato' => 'N', 'default' => '237', ), '09.0' => array( //080 a 094 'digitos' => 15, 'formato' => 'A', 'default' => 'Bradesco', ), '10.0' => array( //095 a 100 'digitos' => 6, 'formato' => 'N', 'default' => '', //DDMMAA ), '11.0' => array( //101 a 108 'digitos' => 8, 'formato' => 'A', 'default' => '', //Branco ), '12.0' => array( //109 a 110 'digitos' => 2, 'formato' => 'A', 'default' => 'MX', //MX Pág. 21. ), '13.0' => array( //111 a 117 'digitos' => 7, 'formato' => 'N', 'default' => '', //Sequencial Pág. 21. ), '14.0' => array( //118 a 394 'digitos' => 277, 'formato' => 'A', 'default' => '', //Branco ), '15.0' => array( //395 a 400 'digitos' => 6, 'formato' => 'N', 'default' => '000001', ), //fim bradesco ); //Transação do Tipo 1 (Obrigatório - Remessa) protected $transacaoTipo1Arquivo = array( '01.1' => array( //001 a 001 'digitos' => 1, 'formato' => 'N', 'default' => '1', ), '02.1' => array( //002 a 006 opcional 'digitos' => 5, 'formato' => 'N', 'default' => '00000', ), '03.1' => array( //007 a 007 opcional 'digitos' => 1, 'formato' => 'A', 'default' => '', ), '04.1' => array( //008 a 012 opcional 'digitos' => 5, 'formato' => 'N', 'default' => '00000', ), '05.1' => array( //013 a 019 opcional 'digitos' => 7, 'formato' => 'N', 'default' => '0000000', ), '06.1' => array( //020 a 020 opcional 'digitos' => 1, 'formato' => 'A', 'default' => '', ), '07.1' => array( //021 a 037 'digitos' => 17, 'formato' => 'A', 'default' => '', ), '08.1' => array( //038 a 062 'digitos' => 25, 'formato' => 'A', 'default' => '', ), '09.1' => array( //063 a 065 'digitos' => 3, 'formato' => 'N', 'default' => '', //caso tenha débito automático, setar 237 por default ), '10.1' => array( //066 a 066 'digitos' => 1, 'formato' => 'N', 'default' => '0', ), '11.1' => array( //067 a 070 'digitos' => 4, 'formato' => 'N', 'default' => '', ), '12.1' => array( //071 a 081 'digitos' => 11, 'formato' => 'N', 'default' => '', ), '13.1' => array( //082 a 082 'digitos' => 1, 'formato' => 'A', 'default' => '', ), '14.1' => array( //083 a 092 'digitos' => 10, 'formato' => 'N', 'default' => '', ), '15.1' => array( //093 a 093 'digitos' => 1, 'formato' => '', 'default' => '2', // 2 = Cliente emite e o Banco somente processa o registro ), '16.1' => array( //094 a 094 'digitos' => 1, 'formato' => 'A', 'default' => 'N', //N= Não registra na cobrança. //Diferente de N registra e emite //Boleto. ), '17.1' => array( //095 a 104 'digitos' => 10, 'formato' => 'A', 'default' => '', //Brancos ), '18.1' => array( //105 a 105 opcional 'digitos' => 1, 'formato' => 'A', 'default' => '', ), '19.1' => array( //106 a 106 opcional 'digitos' => 1, 'formato' => 'N', 'default' => '', ), '20.1' => array( //107 a 108 'digitos' => 2, 'formato' => 'A', 'default' => '', //Branco ), '21.1' => array( //109 a 110 'digitos' => 2, 'formato' => 'N', 'default' => '01', ), '22.1' => array( //111 a 120 'digitos' => 10, 'formato' => 'A', 'default' => '', //Documento ), '23.1' => array( //121 a 126 'digitos' => 6, 'formato' => 'N', 'default' => '', ), '24.1' => array( //127 a 139 'digitos' => 13, 'formato' => 'N', 'default' => '', //Valor do Título (preencher sem ponto e sem vírgula) ), '25.1' => array( //140 a 142 'digitos' => 3, 'formato' => 'N', 'default' => '000', //Preencher com zeros ), '26.1' => array( //143 a 147 'digitos' => 5, 'formato' => 'N', 'default' => '00000', //Preencher com zeros ), '27.1' => array( //148 a 149 'digitos' => 2, 'formato' => 'N', 'default' => '01' //01-Duplicata //02-Nota Promissória //03-Nota de Seguro //04-Cobrança Seriada //05-Recibo //10-Letras de Câmbio //11-Nota de Débito //12-Duplicata de Serv. //30-Boleto de Proposta //99-Outros ), '28.1' => array( //150 a 150 'digitos' => 1, 'formato' => 'A', 'default' => 'N', ), '29.1' => array( //151 a 156 'digitos' => 6, 'formato' => 'N', 'default' => '', //DDMMAA ), '30.1' => array( //157 a 158 'digitos' => 2, 'formato' => 'N', 'default' => '', ), '31.1' => array( //159 a 160 'digitos' => 2, 'formato' => 'N', 'default' => '', ), '32.1' => array( //161 a 173 'digitos' => 13, 'formato' => 'N', 'default' => '', //Mora por Dia de Atraso Vide obs Pág. 21. ), '33.1' => array( //174 a 179 'digitos' => 6, 'formato' => 'N', 'default' => '', //DDMMAA ), '34.1' => array( //180 a 192 'digitos' => 13, 'formato' => 'N', 'default' => '', //Valor Desconto ), '35.1' => array( //193 a 205 'digitos' => 13, 'formato' => 'N', 'default' => '', //Valor do IOF -- Vibe obs: Pág. 21 ), '36.1' => array( //206 a 218 'digitos' => 13, 'formato' => 'N', 'default' => '', //Valor Abatimento ), '37.1' => array( //219 a 220 'digitos' => 2, 'formato' => 'N', 'default' => '', //02 - CNPJ; 01 - CPF; ), '38.1' => array( //221 a 234 'digitos' => 14, 'formato' => 'N', 'default' => '', //CNPJ/ CPF - Vide Obs. Pág. 121 ), '39.1' => array( //235 a 274 'digitos' => 40, 'formato' => 'A', 'default' => '', //Nome do Pagador ), '40.1' => array( //275 a 314 'digitos' => 40, 'formato' => 'A', 'default' => '', //Endereço do Pagador ), '41.1' => array( //315 a 326 'digitos' => 12, 'formato' => 'A', 'default' => '', //Vide Obs. Pág. 22 //Campo livre para uso da Empresa. A mensagem enviada nesse campo será impressa somente no //boleto e não será confirmada no Arquivo Retorno. ), '42.1' => array( //327 a 331 'digitos' => 5, 'formato' => 'N', 'default' => '', //CEP Pagador ), '43.1' => array( //332 a 334 'digitos' => 3, 'formato' => 'N', 'default' => '', //Sufixo ), '44.1' => array( //335 a 394 'digitos' => 60, 'formato' => 'A', 'default' => '', //Decomposição Vibe Obs. Pág. 22 ), '45.1' => array( //395 a 400 'digitos' => 6, 'formato' => 'N', 'default' => '', //Nº Seqüencial do Registro ), //fim bradesco ); protected $trailerArquivo = array( '01.9' => array( 'digitos' => 1, 'formato' => 'N', 'default' => '9', ), '02.9' => array( 'digitos' => 393, 'formato' => 'A', 'default' => '', //BRANCO ), '03.9' => array( 'digitos' => 6, 'formato' => 'N', 'default' => '', ), ); protected $empresaId; protected $contaId; protected $bancoId; protected $dataVencimentoDe; protected $dataVencimentoA; protected $numero; protected $codigoRemessa; protected $dataCriacaoArquivo; protected $pagamentos = array(); public function __construct($empresaId, $dataVencimentoDe, $dataVencimentoA, $lancamentos, $codigoRemessa, $contaId, $bancoId) { $lancamento = Financeiro_Model_Container::getLancamento(); $this->empresaId = $empresaId; $this->contaId = $contaId; $this->bancoId = $bancoId; $this->dataVencimentoDe = $dataVencimentoDe; $this->dataVencimentoA = $dataVencimentoA; $this->codigoRemessa = $codigoRemessa; $this->pagamentos = $lancamento->getLancamentosRemessa(array( 'empresa_id' => $empresaId, 'data_vencimento_de' => $dataVencimentoDe, 'data_vencimento_a' => $dataVencimentoA, 'lancamentos' => $lancamentos, 'conta_id' => $contaId, 'banco_id' => $bancoId ), array( 'lancamento.empresa_id', 'data_vencimento ASC' ) ); } public function getNumero() { return $this->numero; } protected function formatar(array $tabela, array $valores) { require_once 'Core/Filter/Alnum.php'; require_once 'Core/Filter/RemoverAcentos.php'; foreach ( $tabela as $sCod => $sInfo ) { if( !isset($valores[$sCod]) ){ $valores[$sCod] = $sInfo['default']; } if( $sInfo['formato'] == 'N' ){ $filter = new Zend_Filter_Digits(); } else { $filter = new Zend_Filter(); $filter->addFilter(new Core_Filter_Alnum(true, true)) ->addFilter(new Core_Filter_RemoverAcentos()) ->addFilter(new Zend_Filter_StringToUpper()); } $valores[$sCod] = $filter->filter($valores[$sCod]); $digitos = ($sInfo['formato'] == 'N' && isset($sInfo['decimais']) && $sInfo['decimais']) ? $sInfo['digitos'] + $sInfo['decimais'] : $sInfo['digitos']; if( strlen($valores[$sCod]) < $digitos ){ $restante = $digitos - strlen($valores[$sCod]); for ( $i = 0; $i < $restante; $i++ ) { if( $sInfo['formato'] == 'N' ){ $valores[$sCod] = '0' . $valores[$sCod]; } else { $valores[$sCod] .= ' '; } } } else if( strlen($valores[$sCod]) > $digitos ){ $valores[$sCod] = substr($valores[$sCod], 0, $digitos); } if( $sInfo['formato'] == 'N' && isset($sInfo['decimais']) && $sInfo['decimais'] ){ for ( $j = 0; $j < $sInfo['decimais']; $j++ ) { $valores[$sCod] .= '0'; } } } ksort($valores); return $valores; } public function _geraCodigoBanco($numero) { $parte1 = substr($numero, 0, 3); $parte2 = $this->modulo_11($parte1); return $parte1 . '-' . $parte2; } protected function gerarHeaderArquivo($empresa, $conta) { $sequencialRemessa = $this->_gerarSequenciaRemessa(); $h = array( '06.0' => $conta->codigo_cedente, '07.0' => $empresa->razao_social, '10.0' => $this->dataCriacaoArquivo, '13.0' => $sequencialRemessa, ); return $this->formatar($this->headerArquivo, $h); } //O número de remessa deve iniciar de 0000001 e incrementado de + 1 a cada NOVO Arquivo //Remessa, com o objetivo de evitar que ocorra duplicidade de arquivo não podendo, em hipótese //alguma, ser repetida ou zerada. public function _gerarSequenciaRemessa() { $sequencialNumero = Core_Refatorar::formatarNumero( $this->getNumero(), 7); return $sequencialNumero; } protected function gerarTransacaoTipo1Arquivo($pagamento, $nSequencial) { $data = Zend_Date::now(); $nossoNumero = $pagamento->id; $dataVencimento = new Zend_Date($pagamento->data_vencimento); $dataDesconto = (clone $dataVencimento)->subDay($pagamento->dias_antecipacao ?? 0); $valor = str_replace(".", "", $pagamento->valor); $identificacaoEmpresaBeneficiaria = '0' . Core_Refatorar::formatarNumero($pagamento->carteira, 3) . Core_Refatorar::formatarNumero($pagamento->agencia, 5) . Core_Refatorar::formatarNumero($pagamento->conta, 7) . Core_Refatorar::formatarNumero($pagamento->conta_dv, 1); $cepSemSufixo = substr($pagamento->cep, 0, 5); $sufixoCep = substr($pagamento->cep, -3); $enderecoCompleto = $pagamento->endereco . ", " . $pagamento->cidade . ", " . $pagamento->uf; $valorCobradoPorDiaAtraso = ''; $percentualMulta = ''; if( $pagamento->multa == 2 ){ $valorCobradoPorDiaAtraso = str_replace(".", "", $pagamento->valor * $pagamento->percentual_multa / 100); $percentualMulta = !empty($pagamento->percentual_multa) ? number_format($pagamento->percentual_multa, 2, '', '.') : ""; } //nosso número (sem dv) é 11 digitos $nnum = $this->formataNumero($pagamento->id, 11, 0); //dv do nosso numero $dvNossoNumero = $this->digitoVerificadorNossoNumero($pagamento->carteira . $nnum); $t1 = array( '07.1' => $identificacaoEmpresaBeneficiaria, '08.1' => $nossoNumero, '12.1' => $nnum, '13.1' => $dvNossoNumero, '15.1' => $pagamento->emissao_bloqueto, '22.1' => $pagamento->numero_documento, '23.1' => $dataVencimento->get('ddMMyy'), //padrão DDMMAA '24.1' => $valor, '29.1' => $data->get('ddMMyy'), '37.1' => $pagamento->tipo_inscricao_pagador, '38.1' => $pagamento->cpf_candidato, '39.1' => $pagamento->candidato, '40.1' => $enderecoCompleto, '42.1' => $cepSemSufixo, '43.1' => $sufixoCep, '45.1' => $nSequencial ); return $this->formatar($this->transacaoTipo1Arquivo, $t1); } protected function gerarTrailerArquivo($nSequencial) { $t = array( '03.9' => $nSequencial ); return $this->formatar($this->trailerArquivo, $t); } public function digitoVerificadorNossoNumero($numero) { $resto2 = $this->modulo_11($numero, 7, 1); $digito = 11 - $resto2; if( $digito == 10 ){ $dv = "P"; } elseif( $digito == 11 ){ $dv = 0; } else { $dv = $digito; } return $dv; } /** * Pega o digito verificador: * nossonumero * agencia * conta * campo 4 da linha digitavel */ public function modulo_11($num, $base = 7, $r = 0) { $soma = 0; $fator = 2; for ( $i = strlen($num); $i > 0; $i-- ) { $numeros[$i] = substr($num, $i - 1, 1); $parcial[$i] = $numeros[$i] * $fator; $soma += $parcial[$i]; if( $fator == $base ){ $fator = 1; } $fator++; } if( $r == 0 ){ $soma *= 10; $digito = $soma % 11; if( $digito == 10 ){ $digito = 'X'; } if( strlen($num) == '43' ){ //então estamos checando a linha digitável if( $digito == '0' or $digito == 'X' or $digito > 9 ){ $digito = 1; } } return $digito; } elseif( $r == 1 ){ $resto = $soma % 11; return $resto; } } public function gerar() { if( count($this->pagamentos) == 0 ){ throw new Exception('Lista de lançamentos vazia'); } $mEmpresa = Operacional_Model_Container::getEmpresa(); $mConta = Financeiro_Model_Container::getConta(); $rows = array(); $arquivo = array(); $qtdRegistros = 1; $arquivoRemessa = Financeiro_Model_Container::getArquivoRemessa(); $remessa = $arquivoRemessa->createRow(array( 'usuario_id' => Yuppie_Auth::getIdentity()->id, 'data_criacao' => Zend_Date::now()->get('yyyy-MM-dd HH:mm:ss'), 'empresa_id' => $this->empresaId, 'data_vencimento_de' => $this->dataVencimentoDe, 'data_vencimento_a' => $this->dataVencimentoA, 'banco_id' => $this->bancoId )); $this->dataCriacaoArquivo = Zend_Date::now()->get('ddMMyy'); $this->numero = $remessa->save(); $empresa = $mEmpresa->findById($this->empresaId); $conta = $mConta->findById($this->contaId); $rows['headerArquivo'] = $this->gerarHeaderArquivo($empresa, $conta); $arquivo[] = implode('', $rows['headerArquivo']); $numeroSequencial = 2; $remessasLancadas = Financeiro_Model_Container::getRemessasLancadas(); $lancamento = Financeiro_Model_Container::getLancamento(); foreach ( $this->pagamentos as $pagamento ) { $rows['transacaoTipo1'] = $this->gerarTransacaoTipo1Arquivo($pagamento, $numeroSequencial++); $arquivo[] = implode('', $rows['transacaoTipo1']); $re = $remessasLancadas->createRow( array( 'lancamento_id' => $pagamento->id, 'arquivo_remessa_id' => $this->numero, 'codigo_remessa' => !empty($pagamento->codigo_remessa) ? $pagamento->codigo_remessa : $this->codigoRemessa )); if( $re->save() ){ //caso tenha gerado remessa, seta a flag no lançamento e o código da remessa $lancamento->update(array( 'gerado_remessa' => 1, 'codigo_remessa' => !empty($pagamento->codigo_remessa) ? $pagamento->codigo_remessa : $this->codigoRemessa ), "id = " . $pagamento->id); } } foreach ( $rows as $row ) { $qtdRegistros += count($row); } $arquivo[] = implode('', $this->gerarTrailerArquivo($numeroSequencial++)); return implode(self::QUEBRA_LINHA, $arquivo) . self::QUEBRA_LINHA; } public function formataNumero($numero, $loop, $insert, $tipo = 'geral') { if( $tipo == 'geral' ){ $numero = str_replace(',', '', $numero); while ( strlen($numero) < $loop ) { $numero = $insert . $numero; } } if( $tipo == 'valor' ){ // retira as virgulas, formata o numero, preenche com zeros $numero = str_replace(',', '', $numero); while ( strlen($numero) < $loop ) { $numero = $insert . $numero; } } if( $tipo = 'convenio' ){ while ( strlen($numero) < $loop ) { $numero = $numero . $insert; } } return $numero; } }
💾 保存文件
← 返回文件管理器