├── .codeclimate.yml
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── composer.json
├── phpunit.xml.dist
├── src
└── Cnab
│ ├── Banco.php
│ ├── CodigoCarteira.php
│ ├── Especie.php
│ ├── Factory.php
│ ├── Format
│ ├── Field.php
│ ├── Identifier.php
│ ├── Linha.php
│ ├── Picture.php
│ └── YamlLoad.php
│ ├── Instrucao.php
│ ├── Remessa
│ ├── Cnab240
│ │ ├── Arquivo.php
│ │ ├── Detalhe.php
│ │ ├── HeaderArquivo.php
│ │ ├── HeaderLote.php
│ │ ├── SegmentoP.php
│ │ ├── SegmentoQ.php
│ │ ├── SegmentoR.php
│ │ ├── TrailerArquivo.php
│ │ └── TrailerLote.php
│ ├── Cnab400
│ │ ├── Arquivo.php
│ │ ├── Detalhe.php
│ │ ├── DetalheMulta.php
│ │ ├── Header.php
│ │ └── Trailer.php
│ └── IArquivo.php
│ └── Retorno
│ ├── Cnab240
│ ├── Arquivo.php
│ ├── Detalhe.php
│ ├── HeaderArquivo.php
│ ├── HeaderLote.php
│ ├── Lote.php
│ ├── SegmentoT.php
│ ├── SegmentoU.php
│ ├── SegmentoW.php
│ ├── TrailerArquivo.php
│ └── TrailerLote.php
│ ├── Cnab400
│ ├── Arquivo.php
│ ├── Detalhe.php
│ ├── Header.php
│ └── Trailer.php
│ ├── CodigoOcorrencia.php
│ ├── IArquivo.php
│ ├── IDetalhe.php
│ └── Linha.php
└── tests
├── Cnab
├── BancoTest.php
├── Format
│ ├── LinhaTest.php
│ ├── PictureTest.php
│ └── YamlLoadTest.php
├── Remessa
│ ├── Cnab240
│ │ ├── BancoDoBrasilTest.php
│ │ └── CaixaTest.php
│ └── Cnab400
│ │ └── ArquivoTest.php
└── Retorno
│ ├── Cnab240
│ └── ArquivoTest.php
│ ├── Cnab400
│ └── ArquivoTest.php
│ └── CodigoOcorrenciaTest.php
├── bootstrap.php
├── exemplo_gerar_teste.php
└── fixtures
├── cnab240
├── retorno_bb.ret
├── retorno_cnab240_caixa.ret
└── retorno_santander.ret
└── cnab400
├── retorno-cb030400-bradesco.ret
├── retorno-cnab400-bb.ret
└── retorno-cnab400-itau.ret
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | languages:
2 | Ruby: false
3 | JavaScript: false
4 | PHP: true
5 | exclude_paths:
6 | - "vendor/*"
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Vim
2 | *.swp
3 | *.swo
4 | bin
5 | vendor
6 | composer.phar
7 | phpunit.xml
8 | composer.lock
9 | nbproject
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | script: phpunit --verbose --coverage-text
3 |
4 | php:
5 | - 5.4
6 | - 5.5
7 | - 5.6
8 | - 7.0
9 |
10 | before_script:
11 | - "composer install -v"
12 |
13 | after_script:
14 | - "phpunit --testdox"
15 |
16 | after_script:
17 | - "phpunit --testdox"
18 | - "phpunit --coverage-clover build/logs/clover.xml"
19 | - "bin/test-reporter --stdout > codeclimate.json; curl -X POST -d @codeclimate.json -H 'Content-Type: application/json' -H 'User-Agent: Code Climate (PHP Test Reporter v0.1.1)' https://codeclimate.com/test_reports"
20 |
21 | addons:
22 | code_climate:
23 | repo_token: 62106545f2b8d419b073155b0af4bd0b9b3233707007fd8950f453c103ad834d
24 |
25 | notifications:
26 | webhooks:
27 | urls:
28 | - https://webhooks.gitter.im/e/4fbdd69a8426f4b5ae9a
29 | on_success: change # options: [always|never|change] default: always
30 | on_failure: always # options: [always|never|change] default: always
31 | on_start: never # options: [always|never|change] default: always
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Anderson Danilo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | CnabPHP
2 | =======
3 |
4 | [](https://gitter.im/andersondanilo/CnabPHP?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
5 |
6 | [](http://travis-ci.org/andersondanilo/CnabPHP)
7 | [](https://packagist.org/packages/andersondanilo/cnab_php)
8 | [](https://packagist.org/packages/andersondanilo/cnab_php)
9 | [](https://codeclimate.com/github/andersondanilo/CnabPHP)
10 | [](https://codeclimate.com/github/andersondanilo/CnabPHP/coverage)
11 |
12 |
13 | Projeto para criar arquivos de remessas e processar arquivos de retorno no formato CNAB, utilizado nos bancos geralmente para boleto bancário.
14 |
15 |
16 | ## Funcionalidades
17 |
18 | * Leitura e geração de arquivos de retorno e remessa nos formatos CNAB 240 e 400
19 |
20 | | Banco | Versão da Remessa | Versão do Retorno |
21 | |-----------------|--------------------|--------------------|
22 | | Banco do Brasil | 240 (Beta) | 240 e 400 |
23 | | Bradesco | | 240 |
24 | | Caixa | 240 | 240 e 400 |
25 | | Itaú | 400 | 400 |
26 | | Santander | | 240 |
27 |
28 | ## Instalação
29 | ### Composer
30 | Se você já conhece o **Composer**, adicione a dependência abaixo à diretiva *"require"* no seu **composer.json**:
31 | ```
32 | "andersondanilo/cnab_php": "1.3.*"
33 | ```
34 |
35 | ## Como Usar
36 | ### Lendo um arquivo de Retorno
37 | ```php
38 | $cnabFactory = new Cnab\Factory();
39 | $arquivo = $cnabFactory->createRetorno('AQUI VAI O CAMINHO DO ARQUIVO DE RETORNO, EX: RET1010.RET');
40 | $detalhes = $arquivo->listDetalhes();
41 | foreach($detalhes as $detalhe) {
42 | if($detalhe->getValorRecebido() > 0) {
43 | $nossoNumero = $detalhe->getNossoNumero();
44 | $valorRecebido = $detalhe->getValorRecebido();
45 | $dataPagamento = $detalhe->getDataOcorrencia();
46 | $carteira = $detalhe->getCarteira();
47 | // você já tem as informações, pode dar baixa no boleto aqui
48 | }
49 | }
50 | ```
51 | ### Criando um arquivo de remessa
52 |
53 | Consulte na wiki: https://github.com/andersondanilo/CnabPHP/wiki/Criando-um-arquivo-de-remessa
54 |
55 | ## Como Contribuir
56 | Você pode contribuir com testes (unitários ou manuais), ou adaptando o formato para outro banco através do projeto cnab_yaml (https://github.com/andersondanilo/cnab_yaml) (que é utilizado pelo cnab_php). [Leia a wiki](https://github.com/andersondanilo/CnabPHP/wiki)
57 |
58 | O projeto está usando o Waffle para gerenciar o status da impleentação de novas remessas e retornos:
59 |
60 | [](http://waffle.io/andersondanilo/CnabPHP)
61 |
62 |
63 | ## Licença
64 | Este projeto esta sobre a licença MIT
65 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "andersondanilo/cnab_php",
3 | "type": "library",
4 | "description": "Projeto para criar arquivos de remessas e processar arquivos de retorno no formato CNAB",
5 | "keywords": ["boleto", "remessa", "retorno"],
6 | "licence": "MIT",
7 | "authors": [
8 | {
9 | "name": "Anderson Danilo",
10 | "email": "andersondanilo.souza@gmail.com"
11 | },
12 | {
13 | "name": "Hermenegildo Marin Junior",
14 | "email": "hmarinjr@gmail.com"
15 | }
16 | ],
17 | "require-dev": {
18 | "phpunit/phpunit": "3.7.*",
19 | "phpunit/php-code-coverage": "1.2.*",
20 | "codeclimate/php-test-reporter": "dev-master"
21 | },
22 | "require": {
23 | "andersondanilo/cnab_yaml": "~1.3",
24 | "php": ">=5.4.0",
25 | "mustangostang/spyc": "0.5.*"
26 | },
27 | "autoload": {
28 | "psr-4": {
29 | "Cnab\\": "src/Cnab"
30 | }
31 | },
32 | "config": {
33 | "bin-dir": "bin"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 | tests
11 |
12 |
13 |
14 |
15 | src
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/Cnab/Banco.php:
--------------------------------------------------------------------------------
1 | self::BANCO_DO_BRASIL,
18 | 'nome_do_banco' => 'BANCO DO BRASIL S.A.',
19 | );
20 | } elseif ($codigo == self::ITAU) {
21 | return array(
22 | 'codigo_do_banco' => self::ITAU,
23 | 'nome_do_banco' => 'BANCO ITAU SA',
24 | );
25 | } elseif ($codigo == self::CEF) {
26 | return array(
27 | 'codigo_do_banco' => self::CEF,
28 | 'nome_do_banco' => 'CAIXA ECONOMICA FEDERAL',
29 | );
30 | } elseif ($codigo == self::SANTANDER) {
31 | return array(
32 | 'codigo_do_banco' => self::SANTANDER,
33 | 'nome_do_banco' => 'BANCO SANTANDER (BRASIL) S/A',
34 | );
35 | } elseif ($codigo == self::BRADESCO) {
36 | return array(
37 | 'codigo_do_banco' => self::BRADESCO,
38 | 'nome_do_banco' => 'BRADESCO',
39 | );
40 | } else {
41 | return false;
42 | }
43 | }
44 |
45 | public static function existBanco($codigo_banco)
46 | {
47 | $banco = self::getBanco($codigo_banco);
48 |
49 | return $banco ? true : false;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Cnab/CodigoCarteira.php:
--------------------------------------------------------------------------------
1 | identifyFile($filename);
68 |
69 | if (!$format) {
70 | throw new \Exception('Formato do arquivo não identificado');
71 | }
72 |
73 | if ($format['tipo'] != 'retorno') {
74 | throw new \Exception('Este não é um arquivo de retorno');
75 | }
76 |
77 | if (!$format['banco']) {
78 | throw new \Exception('Banco não suportado');
79 | }
80 |
81 | if (!\Cnab\Banco::existBanco($format['banco'])) {
82 | throw new \Exception('Banco não suportado');
83 | }
84 |
85 | // por enquanto só suporta o Cnab400
86 |
87 | if ($format['bytes'] == 400) {
88 | return new Retorno\Cnab400\Arquivo($format['banco'], $filename, $format['layout_versao']);
89 | } elseif ($format['bytes'] == 240) {
90 | return new Retorno\Cnab240\Arquivo($format['banco'], $filename, $format['layout_versao']);
91 | } else {
92 | throw new \Exception('Formato não suportado');
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/Cnab/Format/Field.php:
--------------------------------------------------------------------------------
1 | options = $options;
25 | $this->nome = $nome;
26 | $this->cnabLinha = $linha;
27 | $this->format = $format;
28 | $this->pos_start = $pos_start;
29 | $this->pos_end = $pos_end;
30 | $this->length = ($pos_end + 1) - $pos_start;
31 |
32 | $p_length = Picture::getLength($this->format);
33 | if ($p_length > $this->length) {
34 | throw new \Exception("Picture length of '$this->nome' need more positions than $pos_start : $pos_end");
35 | } elseif ($p_length < $this->length) {
36 | throw new \Exception("Picture length of '$this->nome' need less positions than $pos_start : $pos_end");
37 | }
38 | }
39 |
40 | public function set($valor)
41 | {
42 | if ($valor === false || is_null($valor)) {
43 | throw new \Exception("'$this->nome' dont be false or null");
44 | }
45 |
46 | $this->valor_decoded = $valor;
47 |
48 | try {
49 | $this->valor_encoded = Picture::encode($valor, $this->format, $this->options);
50 | } catch (\Exception $e) {
51 | trigger_error("Error in field '$this->nome': ".$e->getMessage(), E_USER_NOTICE);
52 | throw $e; // para exibir o backtrace
53 | }
54 |
55 | $len = strlen($this->valor_encoded);
56 | if ($len != $this->length) {
57 | throw new \Exception("'$this->nome' have length '$len', but field need length $this->length");
58 | }
59 | }
60 |
61 | public function getValue()
62 | {
63 | return $this->valor_decoded;
64 | }
65 |
66 | public function getName()
67 | {
68 | return $this->nome;
69 | }
70 |
71 | public function getEncoded()
72 | {
73 | if (is_null($this->valor_encoded)) {
74 | throw new \Exception("'$this->nome' dont be null, need to set any value");
75 | }
76 |
77 | return $this->valor_encoded;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/Cnab/Format/Identifier.php:
--------------------------------------------------------------------------------
1 | $codigo_banco,
81 | 'tipo' => $tipo,
82 | 'bytes' => $bytes,
83 | 'layout_versao' => $layout_versao,
84 | );
85 |
86 | return $result;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/Cnab/Format/Linha.php:
--------------------------------------------------------------------------------
1 | fields)) {
13 | $this->fields[$key]->set($valor);
14 | } else {
15 | throw new \InvalidArgumentException("field '$key' dont exists");
16 | }
17 | }
18 |
19 | public function __get($key)
20 | {
21 | if (\array_key_exists($key, $this->fields)) {
22 | return $this->fields[$key]->getValue();
23 | } else {
24 | throw new \InvalidArgumentException("field '$key' dont exists");
25 | }
26 | }
27 |
28 | public static function cmpSortFields(Field $field1, Field $field2)
29 | {
30 | return $field1->pos_start > $field2->pos_start ? 1 : -1;
31 | }
32 |
33 | public function addField($nome, $pos_start, $pos_end, $format, $default, $options)
34 | {
35 | foreach ($this->fields as $key => $field) {
36 | $current_pos_start = $field->pos_start;
37 | $current_pos_end = $field->pos_end;
38 |
39 | if (($pos_start >= $current_pos_start && $pos_start <= $current_pos_end) ||
40 | ($pos_end <= $current_pos_end && $pos_end >= $current_pos_start) ||
41 | ($current_pos_start >= $pos_start && $current_pos_start <= $pos_end) ||
42 | ($current_pos_end <= $pos_end && $current_pos_end >= $pos_start)) {
43 | unset($this->fields[$key]);
44 | }
45 | }
46 |
47 | $this->fields[$nome] = new Field($this, $nome, $format, $pos_start, $pos_end, $options);
48 | if ($default !== false) {
49 | $this->fields[$nome]->set($default);
50 | }
51 | }
52 |
53 | public function loadFromString($text)
54 | {
55 | foreach ($this->fields as $field) {
56 | $field->set(Picture::decode(\substr($text, $field->pos_start - 1, $field->length), $field->format, $field->options));
57 | }
58 | }
59 |
60 | public function getEncoded()
61 | {
62 | if ($this->validate()) {
63 | $max_pos_end = 0;
64 | $dados = '';
65 | $fields = $this->fields;
66 | usort($fields, 'self::cmpSortFields');
67 | $lastField = null;
68 | foreach ($fields as $field) {
69 | if ($lastField && $field->pos_start != $lastField->pos_end + 1) {
70 | throw new \Exception("gap between {$lastField->nome} and {$field->nome}");
71 | }
72 | $dados .= $field->getEncoded();
73 | if ($field->pos_end > $max_pos_end) {
74 | $max_pos_end = $field->pos_end;
75 | }
76 | $lastField = $field;
77 | }
78 |
79 | if (strlen($dados) != $max_pos_end) {
80 | throw new \Exception('line length is '.\strlen($dados)." and max pos_end is $max_pos_end");
81 | }
82 |
83 | return $dados;
84 | } else {
85 | return false;
86 | }
87 | }
88 |
89 | public function getFields()
90 | {
91 | return $this->fields;
92 | }
93 |
94 | public function validate()
95 | {
96 | foreach ($this->fields as $fieldNome => $field) {
97 | if ($field->getValue() === null || $field->getValue() === false) {
98 | $this->last_error = "$fieldNome dont be null or false";
99 |
100 | return false;
101 | }
102 | }
103 |
104 | return true;
105 | }
106 |
107 | public function existField($name)
108 | {
109 | $exist = \array_key_exists($name, $this->fields);
110 |
111 | return $exist ? true : false;
112 | }
113 |
114 | public function dump()
115 | {
116 | $dump = '';
117 | $dump .= PHP_EOL;
118 | $dump .= '============= Dump ==============';
119 | $dump .= PHP_EOL;
120 | foreach ($this->fields as $fieldNome => $field) {
121 | $dump .= $fieldNome.': ';
122 | $dump .= $field->getValue();
123 | $dump .= PHP_EOL;
124 | }
125 |
126 | return $dump;
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/src/Cnab/Format/Picture.php:
--------------------------------------------------------------------------------
1 | X|9)\((?P[0-9]+)\)(?P(V9)?)\(?(?P([0-9]+)?)\)?/';
8 |
9 | public static function validarFormato($format)
10 | {
11 | if (\preg_match(self::REGEX_VALID_FORMAT, $format)) {
12 | return true;
13 | } else {
14 | return false;
15 | }
16 | }
17 |
18 | public static function getLength($format)
19 | {
20 | $m = array();
21 | if (preg_match(self::REGEX_VALID_FORMAT, $format, $m)) {
22 | return (int) $m['tamanho1'] + (int) $m['tamanho2'];
23 | } else {
24 | throw new \InvalidArgumentException("'$format' is not a valid format");
25 | }
26 | }
27 |
28 | public static function parseNumber($value)
29 | {
30 | $value = preg_replace('/[^0-9.]/', '', $value);
31 | $value = preg_replace('/^0+/', '', $value);
32 | if ($value) {
33 | return $value;
34 | } else {
35 | return '0';
36 | }
37 | }
38 |
39 | public static function encode($value, $format, $options)
40 | {
41 | $m = array();
42 | if (\preg_match(self::REGEX_VALID_FORMAT, $format, $m)) {
43 | if ($m['tipo1'] == 'X' && !$m['tipo2']) {
44 | $value = \substr($value, 0, $m['tamanho1']);
45 |
46 | return \str_pad($value, (int) $m['tamanho1'], ' ', STR_PAD_RIGHT);
47 | } elseif ($m['tipo1'] == '9') {
48 | if ($value instanceof \DateTime) {
49 | if (@$options['date_format']) {
50 | $value = strftime($options['date_format'], $value->getTimestamp());
51 | } else {
52 | if ((int) $m['tamanho1'] == 8) {
53 | $value = $value->format('dmY');
54 | }
55 |
56 | if ((int) $m['tamanho1'] == 6) {
57 | $value = $value->format('dmy');
58 | }
59 | }
60 | }
61 |
62 | if (!is_numeric($value)) {
63 | throw new \Exception("value '$value' dont is a number, need format $format");
64 | }
65 |
66 | $value = self::parseNumber($value);
67 | $exp = explode('.', $value);
68 | if (!isset($exp[1])) {
69 | $exp[1] = 0;
70 | }
71 | if ($m['tipo2'] == 'V9') {
72 | $tamanho_left = (int) $m['tamanho1'];
73 | $tamanho_right = (int) $m['tamanho2'];
74 | $valor_left = \str_pad($exp[0], $tamanho_left, '0', STR_PAD_LEFT);
75 | if (strlen($exp[1]) > $tamanho_right) {
76 | $extra = strlen($exp[1]) - $tamanho_right;
77 | $extraPow = pow(10, $extra);
78 | $exp[1] = round($exp[1] / $extraPow);
79 | }
80 | $valor_right = \str_pad($exp[1], $tamanho_right, '0', STR_PAD_RIGHT);
81 |
82 | return $valor_left.$valor_right;
83 | } elseif (!$m['tipo2']) {
84 | $value = self::parseNumber($value);
85 |
86 | return \str_pad($value, (int) $m['tamanho1'], '0', STR_PAD_LEFT);
87 | } else {
88 | throw new \InvalidArgumentException("'$format' is not a valid format");
89 | }
90 | }
91 | } else {
92 | throw new \InvalidArgumentException("'$format' is not a valid format");
93 | }
94 | }
95 |
96 | public static function decode($value, $format, $options)
97 | {
98 | $m = array();
99 | if (preg_match(self::REGEX_VALID_FORMAT, $format, $m)) {
100 | if ($m['tipo1'] == 'X' && !$m['tipo2']) {
101 | return rtrim($value);
102 | } elseif ($m['tipo1'] == '9') {
103 | if ($m['tipo2'] == 'V9') {
104 | $tamanho_left = (int) $m['tamanho1'];
105 | $tamanho_right = (int) $m['tamanho2'];
106 | $valor_left = self::parseNumber(substr($value, 0, $tamanho_left));
107 | $valor_right = '0.'.substr($value, $tamanho_left, $tamanho_right);
108 | if ((double) $valor_right > 0) {
109 | return $valor_left + (double) $valor_right;
110 | } else {
111 | return self::parseNumber($valor_left);
112 | }
113 | } elseif (!$m['tipo2']) {
114 | return self::parseNumber($value);
115 | } else {
116 | throw new \InvalidArgumentException("'$format' is not a valid format");
117 | }
118 | }
119 | } else {
120 | throw new \InvalidArgumentException("'$format' is not a valid format");
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/Cnab/Format/YamlLoad.php:
--------------------------------------------------------------------------------
1 | codigo_banco = $codigo_banco;
18 | $this->layoutVersao = $layoutVersao;
19 | $this->formatPath = Factory::getCnabFormatPath();
20 | }
21 |
22 | public function validateCollision($fields)
23 | {
24 | foreach ($fields as $name => $field) {
25 | $pos_start = $field['pos'][0];
26 | $pos_end = $field['pos'][1];
27 |
28 | foreach ($fields as $current_name => $current_field) {
29 | if ($current_name === $name) {
30 | continue;
31 | }
32 |
33 | $current_pos_start = $current_field['pos'][0];
34 | $current_pos_end = $current_field['pos'][1];
35 |
36 | if ($current_pos_start > $current_pos_end) {
37 | throw new \DomainException("No campo $current_name a posição inicial ($current_pos_start) deve ser menor ou igual à posição final ($current_pos_end)");
38 | }
39 |
40 | if (($pos_start >= $current_pos_start && $pos_start <= $current_pos_end) ||
41 | ($pos_end <= $current_pos_end && $pos_end >= $current_pos_start)) {
42 | throw new \DomainException("O campo $name colide com o campo $current_name");
43 | }
44 | }
45 |
46 | return true;
47 | }
48 | }
49 |
50 | public function validateArray($array)
51 | {
52 | if (empty($array) || empty($array['generic'])) {
53 | throw new \Exception('arquivo yaml sem campo "generic"');
54 | }
55 |
56 | foreach ($array as $key => $fields) {
57 | $this->validateCollision($fields);
58 | }
59 |
60 | return true;
61 | }
62 |
63 | public function loadArray(Linha $cnabLinha, $array)
64 | {
65 | $this->validateArray($array);
66 |
67 | $keys = array('generic');
68 | if (array_key_exists(sprintf('%03d', $this->codigo_banco), $array)) {
69 | $keys[] = sprintf('%03d', $this->codigo_banco);
70 | }
71 |
72 | foreach ($array as $key => $fields) {
73 | if (in_array($key, $keys)) {
74 | foreach ($fields as $name => $info) {
75 | $picture = $info['picture'];
76 | $start = $info['pos'][0];
77 | $end = $info['pos'][1];
78 | $default = isset($info['default']) ? $info['default'] : false;
79 | $options = $info;
80 |
81 | $cnabLinha->addField($name, $start, $end, $picture, $default, $options);
82 | }
83 | }
84 | }
85 | }
86 |
87 | public function loadYaml($filename)
88 | {
89 | if (!isset(static::$loaded[$filename])) {
90 | if (!file_exists($filename)) {
91 | return;
92 | }
93 | static::$loaded[$filename] = spyc_load_file($filename);
94 | }
95 | return static::$loaded[$filename];
96 | }
97 |
98 | public function loadFormat($cnab, $filename)
99 | {
100 | $banco = sprintf('%03d', $this->codigo_banco);
101 | $filenamePadrao = $this->formatPath.'/'.$cnab.'/generic/'.$filename.'.yml';
102 | $filenameEspecifico = $this->formatPath.'/'.$cnab.'/'.$banco.'/'.$filename.'.yml';
103 |
104 | if ($this->layoutVersao != null && $this->codigo_banco == 104) {
105 | // Usado quando o banco possuir mais de uma versao de Layout
106 | $filenameEspecifico = $this->formatPath.'/'.$cnab.'/'.$banco.'/'.$this->layoutVersao.'/'.$filename.'.yml';
107 | }
108 |
109 | if (!file_exists($filenamePadrao) && !file_exists($filenameEspecifico)) {
110 | throw new \Exception('Arquivo não encontrado '.$filename);
111 | }
112 |
113 | $arrayPadrao = $this->loadYaml($filenamePadrao);
114 | $arrayEspecifico = $this->loadYaml($filenameEspecifico);
115 |
116 | $arrayFormat = array();
117 |
118 | if ($arrayPadrao) {
119 | $arrayFormat['generic'] = $arrayPadrao;
120 | }
121 |
122 | if ($arrayEspecifico) {
123 | $arrayFormat[$banco] = $arrayEspecifico;
124 | }
125 |
126 | return $arrayFormat;
127 | }
128 |
129 | public function load(Linha $cnabLinha, $cnab, $filename)
130 | {
131 | $arrayFormat = $this->loadFormat($cnab, $filename);
132 | $this->loadArray($cnabLinha, $arrayFormat);
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/Cnab/Instrucao.php:
--------------------------------------------------------------------------------
1 | codigo_banco = $codigo_banco;
24 | $this->layoutVersao = $layoutVersao;
25 | $this->banco = \Cnab\Banco::getBanco($this->codigo_banco);
26 | //$this->data_gravacao = date('dmY');
27 | }
28 |
29 | public function configure(array $params)
30 | {
31 | $banco = \Cnab\Banco::getBanco($this->codigo_banco);
32 | $campos = array(
33 | 'data_geracao', 'data_gravacao', 'nome_fantasia', 'razao_social', 'cnpj', 'logradouro', 'numero', 'bairro',
34 | 'cidade', 'uf', 'cep',
35 | );
36 |
37 | if ($this->codigo_banco == \Cnab\Banco::CEF) {
38 | $campos[] = 'codigo_cedente';
39 | }
40 |
41 | if($this->codigo_banco == \Cnab\Banco::BANCO_DO_BRASIL) {
42 | $campos[] = 'codigo_convenio';
43 | $campos[] = 'codigo_carteira';
44 | $campos[] = 'variacao_carteira';
45 | $campos[] = 'conta_dv';
46 | }
47 |
48 | if ($this->codigo_banco == \Cnab\Banco::CEF || $this->codigo_banco == \Cnab\Banco::BANCO_DO_BRASIL) {
49 | $campos[] = 'agencia';
50 | $campos[] = 'agencia_dv';
51 | $campos[] = 'conta';
52 | $campos[] = 'operacao';
53 | $campos[] = 'numero_sequencial_arquivo';
54 | }
55 |
56 |
57 |
58 | foreach ($campos as $campo) {
59 | if (array_key_exists($campo, $params)) {
60 | if (strpos($campo, 'data_') === 0 && !($params[$campo] instanceof \DateTime)) {
61 | throw new \Exception("config '$campo' need to be instance of DateTime");
62 | }
63 | $this->configuracao[$campo] = $params[$campo];
64 | } else {
65 | throw new \Exception('Configuração "'.$campo.'" need to be set');
66 | }
67 | }
68 |
69 | foreach ($campos as $key) {
70 | if (!array_key_exists($key, $params)) {
71 | throw new Exception('Configuração "'.$key.'" dont exists');
72 | }
73 | }
74 |
75 | $this->data_geracao = $this->configuracao['data_geracao'];
76 | $this->data_gravacao = $this->configuracao['data_gravacao'];
77 |
78 | $this->headerArquivo = new HeaderArquivo($this);
79 | $this->headerLote = new HeaderLote($this);
80 | $this->trailerLote = new TrailerLote($this);
81 | $this->trailerArquivo = new TrailerArquivo($this);
82 |
83 | $this->headerArquivo->codigo_banco = $this->banco['codigo_do_banco'];
84 | $this->headerArquivo->codigo_inscricao = 2;
85 | $this->headerArquivo->numero_inscricao = $this->prepareText($this->configuracao['cnpj'], '.-/');
86 | $this->headerArquivo->agencia = $this->configuracao['agencia'];
87 | $this->headerArquivo->agencia_dv = $this->configuracao['agencia_dv'];
88 |
89 | if($this->codigo_banco == \Cnab\Banco::BANCO_DO_BRASIL) {
90 | $this->headerArquivo->codigo_convenio = $this->configuracao['codigo_convenio'];
91 | $this->headerArquivo->carteira = $this->configuracao['codigo_carteira'];
92 | $this->headerArquivo->variacao_carteira = $this->configuracao['variacao_carteira'];
93 | $this->headerArquivo->conta = $this->configuracao['conta'];
94 | $this->headerArquivo->conta_dv = $this->configuracao['conta_dv'];
95 | }
96 |
97 | if($this->codigo_banco == \Cnab\Banco::CEF) {
98 | $this->headerArquivo->codigo_cedente = $this->configuracao['codigo_cedente'];
99 | }
100 |
101 | $this->headerArquivo->nome_empresa = $this->configuracao['nome_fantasia'];
102 | $this->headerArquivo->nome_banco = $banco['nome_do_banco'];
103 | $this->headerArquivo->codigo_remessa_retorno = 1;
104 | $this->headerArquivo->data_geracao = $this->configuracao['data_geracao'];
105 | $this->headerArquivo->hora_geracao = $this->configuracao['data_geracao'];
106 | $this->headerArquivo->numero_sequencial_arquivo = $this->configuracao['numero_sequencial_arquivo'];
107 |
108 | if ($this->codigo_banco == \Cnab\Banco::CEF) {
109 | if($this->layoutVersao === 'sigcb') {
110 | $this->headerArquivo->codigo_convenio = 0;
111 | } else {
112 | $codigoConvenio = sprintf(
113 | '%04d%03d%08d',
114 | $params['agencia'],
115 | $params['operacao'],
116 | $params['conta']
117 | );
118 | $codigoConvenio .= $this->mod11($codigoConvenio);
119 | $this->headerArquivo->codigo_convenio = $codigoConvenio;
120 | }
121 | }
122 |
123 | $this->headerLote->codigo_banco = $this->headerArquivo->codigo_banco;
124 | $this->headerLote->lote_servico = 1;
125 | $this->headerLote->tipo_operacao = 'R';
126 | $this->headerLote->codigo_inscricao = $this->headerArquivo->codigo_inscricao;
127 | $this->headerLote->numero_inscricao = $this->headerArquivo->numero_inscricao;
128 | $this->headerLote->agencia = $this->headerArquivo->agencia;
129 | $this->headerLote->agencia_dv = $this->headerArquivo->agencia_dv;
130 |
131 |
132 | if ($this->codigo_banco == \Cnab\Banco::CEF) {
133 | $this->headerLote->codigo_convenio = $this->headerArquivo->codigo_cedente;
134 | $this->headerLote->codigo_cedente = $this->headerArquivo->codigo_cedente;
135 | }
136 |
137 | if ($this->codigo_banco == \Cnab\Banco::BANCO_DO_BRASIL) {
138 | $this->headerLote->codigo_convenio = $this->headerArquivo->codigo_convenio;
139 | $this->headerLote->carteira = $this->headerArquivo->carteira;
140 | $this->headerLote->variacao_carteira = $this->headerArquivo->variacao_carteira;
141 | $this->headerLote->conta = $this->headerArquivo->conta;
142 | $this->headerLote->conta_dv = $this->headerArquivo->conta_dv;
143 | }
144 |
145 | $this->headerLote->nome_empresa = $this->headerArquivo->nome_empresa;
146 | $this->headerLote->numero_sequencial_arquivo = $this->headerArquivo->numero_sequencial_arquivo;
147 | $this->headerLote->data_geracao = $this->headerArquivo->data_geracao;
148 |
149 | if ($this->codigo_banco == \Cnab\Banco::CEF) {
150 | $this->headerLote->tipo_servico = 2;
151 | }
152 |
153 | $this->trailerLote->codigo_banco = $this->headerArquivo->codigo_banco;
154 | $this->trailerLote->lote_servico = $this->headerLote->lote_servico;
155 |
156 | $this->trailerArquivo->codigo_banco = $this->headerArquivo->codigo_banco;
157 | }
158 |
159 | public function mod11($num, $base = 9, $r = 0)
160 | {
161 | $soma = 0;
162 | $fator = 2;
163 | /* Separacao dos numeros */
164 | for ($i = strlen($num); $i > 0; --$i) {
165 | // pega cada numero isoladamente
166 | $numeros[$i] = substr($num, $i - 1, 1);
167 | // Efetua multiplicacao do numero pelo falor
168 | $parcial[$i] = $numeros[$i] * $fator;
169 | // Soma dos digitos
170 | $soma += $parcial[$i];
171 | if ($fator == $base) { // restaura fator de multiplicacao para 2
172 | $fator = 1;
173 | }
174 | ++$fator;
175 | }
176 | /* Calculo do modulo 11 */
177 | if ($r == 0) {
178 | $soma *= 10;
179 | $digito = $soma % 11;
180 | if ($digito == 10) {
181 | $digito = 0;
182 | }
183 |
184 | return $digito;
185 | } elseif ($r == 1) {
186 | $resto = $soma % 11;
187 |
188 | return $resto;
189 | }
190 | }
191 |
192 | public function insertDetalhe(array $boleto, $tipo = 'remessa')
193 | {
194 | $dateVencimento = $boleto['data_vencimento'] instanceof \DateTime ? $boleto['data_vencimento'] : new \DateTime($boleto['data_vencimento']);
195 | $dateCadastro = $boleto['data_cadastro'] instanceof \DateTime ? $boleto['data_cadastro'] : new \DateTime($boleto['data_cadastro']);
196 | $dateJurosMora = clone $dateVencimento;
197 |
198 | $detalhe = new Detalhe($this);
199 |
200 | // SEGMENTO P -------------------------------
201 | $detalhe->segmento_p->codigo_banco = $this->headerArquivo->codigo_banco;
202 | $detalhe->segmento_p->lote_servico = $this->headerLote->lote_servico;
203 | $detalhe->segmento_p->agencia = $this->headerArquivo->agencia;
204 | $detalhe->segmento_p->agencia_dv = $this->headerArquivo->agencia_dv;
205 |
206 | if ($this->codigo_banco == \Cnab\Banco::CEF) {
207 | $detalhe->segmento_p->codigo_cedente = $this->headerArquivo->codigo_cedente;
208 | }
209 |
210 | if ($this->codigo_banco == \Cnab\Banco::BANCO_DO_BRASIL) {
211 | $detalhe->segmento_p->conta = $this->headerArquivo->conta;
212 | $detalhe->segmento_p->conta_dv = $this->headerArquivo->conta_dv;
213 | }
214 |
215 | $detalhe->segmento_p->nosso_numero = $this->formatarNossoNumero($boleto['nosso_numero']);
216 |
217 | if($this->codigo_banco == \Cnab\Banco::BANCO_DO_BRASIL) {
218 | // Informar 1 – para carteira 11/12 na modalidade Simples; 2 ou 3 – para carteira 11/17 modalidade
219 | // Vinculada/Caucionada e carteira 31; 4 – para carteira 11/17 modalidade Descontada e carteira 51; e 7 – para
220 | // carteira 17 modalidade Simples.
221 | if($boleto['carteira'] == 17 && $boleto['codigo_carteira'] == \Cnab\CodigoCarteira::COBRANCA_SIMPLES) {
222 | $detalhe->segmento_p->codigo_carteira = 7;
223 | } else {
224 | $detalhe->segmento_p->codigo_carteira = $boleto['codigo_carteira'];
225 | }
226 | }
227 |
228 | if ($this->layoutVersao === 'sigcb' && $this->codigo_banco == \Cnab\Banco::CEF) {
229 | $detalhe->segmento_p->codigo_carteira = 1; // 1 = Cobrança Simples
230 | $detalhe->segmento_p->modalidade_carteira = $boleto['modalidade_carteira']; // 21 = (título Sem Registro emissão CAIXA)
231 | }
232 |
233 | $detalhe->segmento_p->forma_cadastramento = $boleto['registrado'] ? 1 : 2; // 1 = Com, 2 = Sem Registro
234 | if ($boleto['registrado'] && $this->codigo_banco == \Cnab\Banco::CEF) {
235 | $this->headerLote->tipo_servico = 1;
236 | }
237 | $detalhe->segmento_p->numero_documento = $boleto['numero_documento'];
238 | $detalhe->segmento_p->vencimento = $dateVencimento;
239 | $detalhe->segmento_p->valor_titulo = $boleto['valor'];
240 | $detalhe->segmento_p->especie = $boleto['especie']; // 4 = Duplicata serviço
241 | $detalhe->segmento_p->aceite = $boleto['aceite'];
242 | $detalhe->segmento_p->data_emissao = $dateCadastro;
243 | $detalhe->segmento_p->codigo_juros_mora = isset($boleto['codigo_juros_mora'])?$boleto['codigo_juros_mora']:1; // 1 = Por dia, 2= Taxa Mensal, 3= Isento
244 |
245 | if (!empty($boleto['dias_iniciar_contagem_juros']) && is_numeric($boleto['dias_iniciar_contagem_juros'])) {
246 | $dateJurosMora->modify("+{$boleto['dias_iniciar_contagem_juros']} days");
247 | } else {
248 | $dateJurosMora->modify('+1 day');
249 | }
250 |
251 | $detalhe->segmento_p->data_juros_mora = $dateJurosMora;
252 |
253 | $detalhe->segmento_p->valor_juros_mora = $boleto['juros_de_um_dia'];
254 | if ($boleto['valor_desconto'] > 0) {
255 | $detalhe->segmento_p->codigo_desconto_1 = 1; // valor fixo
256 | $detalhe->segmento_p->data_desconto_1 = $boleto['data_desconto'];
257 | $detalhe->segmento_p->valor_desconto_1 = $boleto['valor_desconto'];
258 | } else {
259 | $detalhe->segmento_p->codigo_desconto_1 = 0; // sem desconto
260 | $detalhe->segmento_p->data_desconto_1 = 0;
261 | $detalhe->segmento_p->valor_desconto_1 = 0;
262 | }
263 | $detalhe->segmento_p->valor_abatimento = 0;
264 | $detalhe->segmento_p->uso_empresa = $boleto['numero_documento'];
265 |
266 | if (!empty($boleto['codigo_protesto']) && !empty($boleto['prazo_protesto'])) {
267 | $detalhe->segmento_p->codigo_protesto = $boleto['codigo_protesto'];
268 | $detalhe->segmento_p->prazo_protesto = $boleto['prazo_protesto'];
269 | } else {
270 | $detalhe->segmento_p->codigo_protesto = 3; // 3 = Não protestar
271 | $detalhe->segmento_p->prazo_protesto = 0;
272 | }
273 |
274 | if ($this->codigo_banco == \Cnab\Banco::BANCO_DO_BRASIL) {
275 | // Campo não tratado pelo sistema. Informar 'zeros'.
276 | // O sistema considera a informação que foi cadastrada na
277 | // sua carteira junto ao Banco do Brasil.
278 | $detalhe->segmento_p->codigo_baixa = 0;
279 | $detalhe->segmento_p->prazo_baixa = 0;
280 | } else {
281 | if(isset($boleto['baixar_apos_dias'])) {
282 | if($boleto['baixar_apos_dias'] === false) {
283 | // não baixar / devolver
284 | $detalhe->segmento_p->codigo_baixa = 2;
285 | $detalhe->segmento_p->prazo_baixa = 0;
286 | } else {
287 | // baixa automática
288 | $detalhe->segmento_p->codigo_baixa = 1;
289 | $detalhe->segmento_p->prazo_baixa = $boleto['baixar_apos_dias'];
290 | }
291 | } else {
292 | $detalhe->segmento_p->codigo_baixa = 0;
293 | $detalhe->segmento_p->prazo_baixa = 0;
294 | }
295 | }
296 |
297 | if (array_key_exists('identificacao_distribuicao', $boleto)) {
298 | $detalhe->segmento_p->identificacao_distribuicao = $boleto['identificacao_distribuicao'];
299 | }
300 |
301 | if ($tipo == 'remessa') {
302 | $detalhe->segmento_p->codigo_ocorrencia = 1;
303 | } elseif ($tipo == 'baixa') {
304 | $detalhe->segmento_p->codigo_ocorrencia = 2;
305 | } else {
306 | throw new \Exception('Tipo de detalhe inválido: '.$tipo);
307 | }
308 |
309 | // SEGMENTO Q -------------------------------
310 | $detalhe->segmento_q->codigo_banco = $this->headerArquivo->codigo_banco;
311 | $detalhe->segmento_q->lote_servico = $this->headerLote->lote_servico;
312 | $detalhe->segmento_q->codigo_ocorrencia = $detalhe->segmento_p->codigo_ocorrencia;
313 | if (@$boleto['sacado_cnpj']) {
314 | $detalhe->segmento_q->sacado_codigo_inscricao = '2';
315 | $detalhe->segmento_q->sacado_numero_inscricao = $this->prepareText($boleto['sacado_cnpj'], '.-/');
316 | $detalhe->segmento_q->nome = $this->prepareText($boleto['sacado_razao_social']);
317 | } else {
318 | $detalhe->segmento_q->sacado_codigo_inscricao = '1';
319 | $detalhe->segmento_q->sacado_numero_inscricao = $this->prepareText($boleto['sacado_cpf'], '.-/');
320 | $detalhe->segmento_q->nome = $this->prepareText($boleto['sacado_nome']);
321 | }
322 | $detalhe->segmento_q->logradouro = $this->prepareText($boleto['sacado_logradouro']);
323 | $detalhe->segmento_q->bairro = $this->prepareText($boleto['sacado_bairro']);
324 | $detalhe->segmento_q->cep = str_replace('-', '', $boleto['sacado_cep']);
325 | $detalhe->segmento_q->cidade = $this->prepareText($boleto['sacado_cidade']);
326 | $detalhe->segmento_q->estado = $boleto['sacado_uf'];
327 | // se o titulo for de terceiro, o sacador é o terceiro
328 | $detalhe->segmento_q->sacador_codigo_inscricao = $this->headerArquivo->codigo_inscricao;
329 | $detalhe->segmento_q->sacador_numero_inscricao = $this->headerArquivo->numero_inscricao;
330 | $detalhe->segmento_q->sacador_nome = $this->headerArquivo->nome_empresa;
331 |
332 | // SEGMENTO R -------------------------------
333 | $detalhe->segmento_r->codigo_banco = $detalhe->segmento_p->codigo_banco;
334 | $detalhe->segmento_r->lote_servico = $detalhe->segmento_p->lote_servico;
335 | $detalhe->segmento_r->codigo_ocorrencia = $detalhe->segmento_p->codigo_ocorrencia;
336 | if ($boleto['valor_multa'] > 0) {
337 | $detalhe->segmento_r->codigo_multa = 1;
338 | $detalhe->segmento_r->valor_multa = $boleto['valor_multa'];
339 | $detalhe->segmento_r->data_multa = $boleto['data_multa'];
340 | } else {
341 | $detalhe->segmento_r->codigo_multa = 0;
342 | $detalhe->segmento_r->valor_multa = 0;
343 | $detalhe->segmento_r->data_multa = 0;
344 | }
345 |
346 | $this->detalhes[] = $detalhe;
347 | }
348 |
349 | public function formatarNossoNumero($nossoNumero)
350 | {
351 | if(!$nossoNumero)
352 | return $nossoNumero;
353 |
354 | if ($this->codigo_banco == \Cnab\Banco::BANCO_DO_BRASIL) {
355 | $codigo_convenio = $this->configuracao['codigo_convenio'];
356 |
357 | if(strlen($codigo_convenio) <= 4) {
358 | # Convênio de 4 digitos
359 | if(strlen($nossoNumero) > 7) {
360 | throw new \InvalidArgumentException(
361 | "Para número de convênio de 4 posições o nosso número deve ter no máximo 7 posições (sem o digito)"
362 | );
363 | }
364 | $number = sprintf('%04d%07d', $codigo_convenio, $nossoNumero);
365 | return $number . $this->mod11($number);
366 | } elseif (strlen($codigo_convenio) <= 6) {
367 | # Convênio de 6 digitos
368 | if(strlen($nossoNumero) > 5) {
369 | throw new \InvalidArgumentException(
370 | "Para número de convênio de 6 posições o nosso número deve ter no máximo 5 posições (sem o digito)"
371 | );
372 | }
373 | $number = sprintf('%06d%05d', $codigo_convenio, $nossoNumero);
374 | return $number . $this->mod11($number);
375 | } else {
376 | if(strlen($nossoNumero) > 10) {
377 | throw new \InvalidArgumentException(
378 | "Para número de convênio de 7 posições o nosso número deve ter no máximo 10 posições"
379 | );
380 | }
381 | $number = sprintf('%07d%010d', $codigo_convenio, $nossoNumero);
382 | return $number;
383 | }
384 | }
385 |
386 | return $nossoNumero;
387 | }
388 |
389 | public function listDetalhes()
390 | {
391 | return $this->detalhes;
392 | }
393 |
394 | private function prepareText($text, $remove = null)
395 | {
396 | $result = strtoupper($this->removeAccents(trim(html_entity_decode($text))));
397 | if ($remove) {
398 | $result = str_replace(str_split($remove), '', $result);
399 | }
400 |
401 | return $result;
402 | }
403 |
404 | private function removeAccents($string)
405 | {
406 | return preg_replace(
407 | array(
408 | '/\xc3[\x80-\x85]/',
409 | '/\xc3\x87/',
410 | '/\xc3[\x88-\x8b]/',
411 | '/\xc3[\x8c-\x8f]/',
412 | '/\xc3([\x92-\x96]|\x98)/',
413 | '/\xc3[\x99-\x9c]/',
414 |
415 | '/\xc3[\xa0-\xa5]/',
416 | '/\xc3\xa7/',
417 | '/\xc3[\xa8-\xab]/',
418 | '/\xc3[\xac-\xaf]/',
419 | '/\xc3([\xb2-\xb6]|\xb8)/',
420 | '/\xc3[\xb9-\xbc]/',
421 | '/\xC2\xAA/',
422 | '/\xC2\xBA/',
423 | ),
424 | str_split('ACEIOUaceiouao', 1),
425 | $this->isUtf8($string) ? $string : utf8_encode($string)
426 | );
427 | }
428 |
429 | private function isUtf8($string)
430 | {
431 | return preg_match('%^(?:
432 | [\x09\x0A\x0D\x20-\x7E]
433 | | [\xC2-\xDF][\x80-\xBF]
434 | | \xE0[\xA0-\xBF][\x80-\xBF]
435 | | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}
436 | | \xED[\x80-\x9F][\x80-\xBF]
437 | | \xF0[\x90-\xBF][\x80-\xBF]{2}
438 | | [\xF1-\xF3][\x80-\xBF]{3}
439 | | \xF4[\x80-\x8F][\x80-\xBF]{2}
440 | )*$%xs',
441 | $string
442 | );
443 | }
444 |
445 | public function getText()
446 | {
447 | $numero_sequencial_lote = 1;
448 | $qtde_registro_lote = 2; // header e trailer = 2
449 | $qtde_titulo_cobranca_simples = 0;
450 | $valor_total_titulo_simples = 0;
451 |
452 | // valida os dados
453 | if (!$this->headerArquivo->validate()) {
454 | throw new \InvalidArgumentException($this->headerArquivo->last_error);
455 | }
456 |
457 | if (!$this->headerLote->validate()) {
458 | throw new \InvalidArgumentException($this->headerLote->last_error);
459 | }
460 |
461 | $dados = $this->headerArquivo->getEncoded().self::QUEBRA_LINHA;
462 | $dados .= $this->headerLote->getEncoded().self::QUEBRA_LINHA;
463 |
464 | foreach ($this->detalhes as $detalhe) {
465 | ++$qtde_titulo_cobranca_simples;
466 | $valor_total_titulo_simples += $detalhe->segmento_p->valor_titulo;
467 | foreach ($detalhe->listSegmento() as $segmento) {
468 | ++$qtde_registro_lote;
469 | $segmento->numero_sequencial_lote = $numero_sequencial_lote++;
470 | }
471 |
472 | if (!$detalhe->validate()) {
473 | throw new \InvalidArgumentException($detalhe->last_error);
474 | }
475 |
476 | $dados .= $detalhe->getEncoded().self::QUEBRA_LINHA;
477 | }
478 |
479 | $this->trailerLote->qtde_registro_lote = $qtde_registro_lote;
480 |
481 | if ($this->codigo_banco == \Cnab\Banco::CEF) {
482 | $this->trailerLote->qtde_titulo_cobranca_simples = $qtde_titulo_cobranca_simples;
483 | $this->trailerLote->valor_total_titulo_simples = $valor_total_titulo_simples;
484 | $this->trailerLote->qtde_titulo_cobranca_caucionada = 0;
485 | $this->trailerLote->valor_total_titulo_caucionada = 0;
486 | $this->trailerLote->qtde_titulo_cobranca_descontada = 0;
487 | $this->trailerLote->valor_total_titulo_descontada = 0;
488 | }
489 |
490 | $this->trailerArquivo->qtde_lotes = 1;
491 | $this->trailerArquivo->qtde_registros = $this->trailerLote->qtde_registro_lote + 2;
492 |
493 | if (!$this->trailerLote->validate()) {
494 | throw new \InvalidArgumentException($this->trailerLote->last_error);
495 | }
496 |
497 | if (!$this->trailerArquivo->validate()) {
498 | throw new \InvalidArgumentException($this->trailerArquivo->last_error);
499 | }
500 |
501 | $dados .= $this->trailerLote->getEncoded().self::QUEBRA_LINHA;
502 | $dados .= $this->trailerArquivo->getEncoded().self::QUEBRA_LINHA;
503 |
504 | return $dados;
505 | }
506 |
507 | public function countDetalhes()
508 | {
509 | return count($this->detalhes);
510 | }
511 |
512 | public function save($filename)
513 | {
514 | $text = $this->getText();
515 |
516 | file_put_contents($filename, $text);
517 |
518 | return $filename;
519 | }
520 | }
521 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab240/Detalhe.php:
--------------------------------------------------------------------------------
1 | segmento_p = new SegmentoP($arquivo);
16 | $this->segmento_q = new SegmentoQ($arquivo);
17 | $this->segmento_r = new SegmentoR($arquivo);
18 | }
19 |
20 | public function validate()
21 | {
22 | $this->last_error = null;
23 | foreach ($this->listSegmento() as $segmento) {
24 | if (!$segmento->validate()) {
25 | $this->last_error = get_class($segmento).': '.$segmento->last_error;
26 | }
27 | }
28 |
29 | return is_null($this->last_error);
30 | }
31 |
32 | /**
33 | * Lista todos os segmentos deste detalhe.
34 | *
35 | * @return array
36 | */
37 | public function listSegmento()
38 | {
39 | return array(
40 | $this->segmento_p,
41 | $this->segmento_q,
42 | $this->segmento_r,
43 | );
44 | }
45 |
46 | /**
47 | * Retorna todas as linhas destes detalhes.
48 | *
49 | * @return string
50 | */
51 | public function getEncoded()
52 | {
53 | $text = array();
54 | foreach ($this->listSegmento() as $segmento) {
55 | $text[] = $segmento->getEncoded();
56 | }
57 |
58 | return implode(Arquivo::QUEBRA_LINHA, $text);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab240/HeaderArquivo.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'header_arquivo');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab240/HeaderLote.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'header_lote');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab240/SegmentoP.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'remessa/detalhe_segmento_p');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab240/SegmentoQ.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'remessa/detalhe_segmento_q');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab240/SegmentoR.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'remessa/detalhe_segmento_r');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab240/TrailerArquivo.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'trailer_arquivo');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab240/TrailerLote.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'trailer_lote');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab400/Arquivo.php:
--------------------------------------------------------------------------------
1 | codigo_banco = $codigo_banco;
21 | $this->layout_versao = $layout_versao;
22 | $this->banco = \Cnab\Banco::getBanco($this->codigo_banco);
23 | //$this->data_gravacao = date('dmY');
24 | }
25 |
26 | public function configure(array $params)
27 | {
28 | $campos = array(
29 | 'data_geracao', 'data_gravacao', 'nome_fantasia', 'razao_social', 'cnpj', 'logradouro', 'numero', 'bairro',
30 | 'cidade', 'uf', 'cep', 'agencia', 'conta'
31 | );
32 |
33 | switch ($this->codigo_banco) {
34 | case \Cnab\Banco::CEF:
35 | $campos[] = 'operacao';
36 | $campos[] = 'codigo_cedente';
37 | $campos[] = 'codigo_cedente_dac';
38 | case \Cnab\Banco::BRADESCO:
39 | $campos[] = 'codigo_cedente';
40 | $campos[] = 'sequencial_remessa';
41 | break;
42 | case \Cnab\Banco::BANCO_DO_BRASIL:
43 | $campos[] = 'agencia_dac';
44 | $campos[] = 'conta_dac';
45 | $campos[] = 'numero_sequencial';
46 | $campos[] = 'numero_convenio';
47 | break;
48 | default:
49 | $campos[] = 'conta_dac';
50 | break;
51 | }
52 |
53 | foreach ($campos as $campo) {
54 | if (array_key_exists($campo, $params)) {
55 | if (strpos($campo, 'data_') === 0 && !($params[$campo] instanceof \DateTime)) {
56 | throw new \Exception("config '$campo' need to be instance of DateTime");
57 | }
58 | $this->configuracao[$campo] = $params[$campo];
59 | } else {
60 | throw new \Exception('Configuração "'.$campo.'" need to be set');
61 | }
62 | }
63 |
64 | foreach ($campos as $key) {
65 | if (!array_key_exists($key, $params)) {
66 | throw new Exception('Configuração "'.$key.'" dont exists');
67 | }
68 | }
69 |
70 | $this->data_geracao = $this->configuracao['data_geracao'];
71 | $this->data_gravacao = $this->configuracao['data_gravacao'];
72 |
73 | $this->header = new Header($this);
74 |
75 | $this->header->codigo_banco = $this->banco['codigo_do_banco'];
76 | $this->header->nome_banco = $this->banco['nome_do_banco'];
77 | $this->header->agencia = $this->configuracao['agencia'];
78 | $this->header->conta = $this->configuracao['conta'];
79 |
80 | switch ($this->codigo_banco) {
81 | case \Cnab\Banco::CEF:
82 | $this->header->codigo_cedente = $this->configuracao['codigo_cedente'];
83 | case \Cnab\Banco::BRADESCO:
84 | $this->header->codigo_cedente = $this->configuracao['codigo_cedente'];
85 | $this->header->sequencial_remessa = $this->configuracao['sequencial_remessa'];
86 | $this->header->razao_social = $this->configuracao['razao_social'];
87 | break;
88 | case \Cnab\Banco::BANCO_DO_BRASIL:
89 | $this->header->agencia_dv = $this->configuracao['agencia_dac'];
90 | $this->header->conta_dv = $this->configuracao['conta_dac'];
91 | $this->header->numero_sequencial = $this->configuracao['numero_sequencial'];
92 | $this->header->convenio_lider = $this->configuracao['numero_convenio'];
93 | break;
94 | default:
95 | $this->header->conta_dv = $this->configuracao['conta_dac'];
96 | break;
97 | }
98 |
99 | $this->header->nome_empresa = $this->configuracao['nome_fantasia'];
100 | $this->header->data_geracao = $this->configuracao['data_geracao']->format('dmy');
101 | }
102 |
103 | public function insertDetalhe(array $boleto, $tipo = 'remessa')
104 | {
105 | $dateVencimento = $boleto['data_vencimento'] instanceof \DateTime ? $boleto['data_vencimento'] : new \DateTime($boleto['data_vencimento']);
106 | $dateCadastro = $boleto['data_cadastro'] instanceof \DateTime ? $boleto['data_cadastro'] : new \DateTime($boleto['data_cadastro']);
107 |
108 | $detalhe = new Detalhe($this);
109 | $complementos = array();
110 |
111 | if ($tipo == 'remessa') {
112 | $detalhe->codigo_ocorrencia = !empty($boleto['codigo_de_ocorrencia']) ? $boleto['codigo_de_ocorrencia'] : '1';
113 |
114 | $detalhe->codigo_inscricao = 2;
115 | $detalhe->numero_inscricao = $this->prepareText($this->configuracao['cnpj'], '.-/');
116 |
117 | if (\Cnab\Banco::BRADESCO == $this->codigo_banco) {
118 | $detalhe->codigo_cedente = $this->header->codigo_cedente;
119 | $detalhe->digito_nosso_numero = $boleto['digito_nosso_numero'];
120 | } else if (\Cnab\Banco::CEF == $this->codigo_banco) {
121 | $detalhe->codigo_cedente = $this->header->codigo_cedente;
122 | $detalhe->taxa_de_permanencia = $boleto['taxa_de_permanencia'];
123 | $detalhe->mensagem = $boleto['mensagem'];
124 | $detalhe->data_multa = $boleto['data_multa'];
125 | $detalhe->valor_multa = $boleto['valor_multa'];
126 | } else if (\Cnab\Banco::BANCO_DO_BRASIL == $this->codigo_banco) {
127 | $detalhe->agencia = $this->header->agencia;
128 | $detalhe->agencia_dv = $this->header->agencia_dv;
129 | $detalhe->conta = $this->header->conta;
130 | $detalhe->conta_dv = $this->header->conta_dv;
131 | $detalhe->numero_convenio = $boleto['numero_convenio'];
132 | $detalhe->variacao_carteira = $boleto['variacao_carteira'];
133 | $detalhe->tipo_cobranca = (isset($boleto['tipo_cobranca']) ?: '');
134 |
135 | } else {
136 | $detalhe->agencia = $this->header->agencia;
137 | $detalhe->conta = $this->header->conta;
138 | $detalhe->conta_dv = $this->header->conta_dv;
139 | $detalhe->codigo_instrucao = '0';
140 | $detalhe->qtde_moeda = '0'; # Este campo deverá ser preenchido com zeros caso a moeda seja o Real.
141 | $detalhe->codigo_carteira = 'I';
142 | $detalhe->uso_banco = '';
143 | $detalhe->data_mora = $boleto['data_multa'];
144 |
145 | if ($boleto['valor_multa'] > 0) {
146 | /*
147 | // Não está presente na documentação disponibilizada no site
148 | // os valores de multa devem ser configurados com o gerente da sua conta
149 | $detalheMulta = new DetalheMulta($this);
150 | if(@$boleto['tipo_multa'] == 'porcentagem')
151 | $detalheMulta->codigo_multa = 2;
152 | else if(!@$boleto['tipo_multa'] || $boleto['tipo_multa'] == 'valor')
153 | $detalheMulta->codigo_multa = 1;
154 | else
155 | throw new Exception('tipo de multa inválido, deve ser "porcentagem" ou "valor"');
156 | $detalheMulta->data_multa = $boleto['data_multa'];
157 | $detalheMulta->valor_multa = $boleto['valor_multa'];
158 | $complementos[] = $detalheMulta;
159 | */
160 | }
161 | }
162 |
163 | /*
164 | Deve ser preenchido na remessa somente quando utilizados, na posição 109-110, os códigos de
165 | ocorrência 35 – Cancelamento de Instrução e 38 – Cedente não concorda com alegação do sacado. Para
166 | os demais códigos de ocorrência este campo deverá ser preenchido com zeros.
167 | */
168 | $detalhe->uso_empresa = isset($boleto['uso_empresa'])
169 | ? $boleto['uso_empresa']
170 | : $boleto['nosso_numero'];
171 | $detalhe->nosso_numero = $boleto['nosso_numero'];
172 |
173 | $detalhe->numero_carteira = $boleto['carteira'];
174 | $detalhe->numero_documento = $boleto['numero_documento'];
175 | $detalhe->vencimento = $dateVencimento->format('dmy');
176 | $detalhe->valor_titulo = $boleto['valor'];
177 | $detalhe->aceite = empty($boleto['aceite']) ? 'N' : $boleto['aceite'];
178 | $detalhe->instrucao1 = $boleto['instrucao1'];
179 | $detalhe->instrucao2 = $boleto['instrucao2'];
180 | $detalhe->especie = $boleto['especie'];
181 | $detalhe->data_emissao = $dateCadastro->format('dmy');
182 |
183 | $sacado_tipo = @$boleto['sacado_tipo'] or $sacado_tipo = 'cpf';
184 |
185 | if ($sacado_tipo == 'cnpj') {
186 | $detalhe->sacado_codigo_inscricao = '2';
187 | /*
188 | * @todo Trocar espécie
189 | */
190 | $detalhe->sacado_numero_inscricao = $this->prepareText($boleto['sacado_cnpj'], '.-/');
191 | $detalhe->nome = $this->prepareText($boleto['sacado_razao_social']);
192 | } else {
193 | $detalhe->sacado_codigo_inscricao = '1';
194 | /*
195 | * @todo Trocar espécie
196 | */
197 | $detalhe->sacado_numero_inscricao = $this->prepareText($boleto['sacado_cpf'], '.-/');
198 | $detalhe->nome = $this->prepareText($boleto['sacado_nome']);
199 | }
200 |
201 | $detalhe->logradouro = $this->prepareText($boleto['sacado_logradouro']);
202 | $detalhe->bairro = $this->prepareText($boleto['sacado_bairro']);
203 | $detalhe->cep = str_replace('-', '', $boleto['sacado_cep']);
204 | $detalhe->cidade = $this->prepareText($boleto['sacado_cidade']);
205 | $detalhe->estado = $boleto['sacado_uf'];
206 | $detalhe->sacador = $this->prepareText($this->configuracao['nome_fantasia']);
207 |
208 | $detalhe->juros_um_dia = $boleto['juros_de_um_dia'];
209 | $detalhe->desconto_ate = $boleto['data_desconto'];
210 | $detalhe->valor_desconto = $boleto['valor_desconto'];
211 | $detalhe->prazo = $boleto['prazo'];
212 | } elseif ($tipo == 'baixa') {
213 | $detalhe->codigo_inscricao = '0';
214 | $detalhe->numero_inscricao = '0';
215 | $detalhe->agencia = $this->header->agencia;
216 | $detalhe->conta = $this->header->conta;
217 | $detalhe->conta_dac = $this->header->dac;
218 | $detalhe->codigo_instrucao = '0';
219 | /*
220 | Deve ser preenchido na remessa somente quando utilizados, na posição 109-110, os códigos de
221 | ocorrência 35 – Cancelamento de Instrução e 38 – Cedente não concorda com alegação do sacado. Para
222 | os demais códigos de ocorrência este campo deverá ser preenchido com zeros.
223 | */
224 | $detalhe->codigo_ocorrencia = $boleto['codigo_de_ocorrencia'];
225 | $detalhe->uso_empresa = $boleto['nosso_numero'];
226 | $detalhe->nosso_numero = $boleto['nosso_numero'];
227 | $detalhe->qtde_moeda = '0'; # Este campo deverá ser preenchido com zeros caso a moeda seja o Real.
228 | $detalhe->numero_carteira = $boleto['carteira'];
229 | $detalhe->codigo_carteira = 'I';
230 | $detalhe->uso_banco = '';
231 | $detalhe->numero_documento = $boleto['numero_documento'];
232 | $detalhe->vencimento = '0';
233 | $detalhe->valor_titulo = $boleto['valor'];
234 | $detalhe->aceite = ' ';
235 | $detalhe->data_emissao = '0';
236 | $detalhe->sacado_codigo_inscricao = '2';
237 | $detalhe->especie = ' ';
238 | $detalhe->sacado_numero_inscricao = '0';
239 | $detalhe->juros_um_dia = $boleto['juros_de_um_dia'];
240 | $detalhe->data_juros = $boleto['data_juros'];
241 |
242 | $detalhe->nome = ' ';
243 | $detalhe->logradouro = ' ';
244 | $detalhe->bairro = ' ';
245 | $detalhe->cep = '0';
246 | $detalhe->cidade = ' ';
247 | $detalhe->estado = ' ';
248 | $detalhe->sacador = ' ';
249 | } else {
250 | throw new Exception('Tipo de $detalhe desconhecido');
251 | }
252 |
253 | $detalhe->codigo_banco = $this->banco['codigo_do_banco'];
254 |
255 | $this->detalhes[] = $detalhe;
256 |
257 | foreach ($complementos as $complemento) {
258 | $this->detalhes[] = $complemento;
259 | }
260 | }
261 |
262 | public function listDetalhes()
263 | {
264 | return $this->detalhes;
265 | }
266 |
267 | private function prepareText($text, $remove = null)
268 | {
269 | $result = strtoupper($this->removeAccents(trim(html_entity_decode($text))));
270 | if ($remove) {
271 | $result = str_replace(str_split($remove), '', $result);
272 | }
273 |
274 | return $result;
275 | }
276 |
277 | private function removeAccents($string)
278 | {
279 | return preg_replace(
280 | array(
281 | '/\xc3[\x80-\x85]/',
282 | '/\xc3\x87/',
283 | '/\xc3[\x88-\x8b]/',
284 | '/\xc3[\x8c-\x8f]/',
285 | '/\xc3([\x92-\x96]|\x98)/',
286 | '/\xc3[\x99-\x9c]/',
287 |
288 | '/\xc3[\xa0-\xa5]/',
289 | '/\xc3\xa7/',
290 | '/\xc3[\xa8-\xab]/',
291 | '/\xc3[\xac-\xaf]/',
292 | '/\xc3([\xb2-\xb6]|\xb8)/',
293 | '/\xc3[\xb9-\xbc]/',
294 | ),
295 | str_split('ACEIOUaceiou', 1),
296 | $this->isUtf8($string) ? $string : utf8_encode($string)
297 | );
298 | }
299 |
300 | private function isUtf8($string)
301 | {
302 | return preg_match('%^(?:
303 | [\x09\x0A\x0D\x20-\x7E]
304 | | [\xC2-\xDF][\x80-\xBF]
305 | | \xE0[\xA0-\xBF][\x80-\xBF]
306 | | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}
307 | | \xED[\x80-\x9F][\x80-\xBF]
308 | | \xF0[\x90-\xBF][\x80-\xBF]{2}
309 | | [\xF1-\xF3][\x80-\xBF]{3}
310 | | \xF4[\x80-\x8F][\x80-\xBF]{2}
311 | )*$%xs',
312 | $string
313 | );
314 | }
315 |
316 | public function __set($name, $value)
317 | {
318 | if (strpos($name, 'data_') === 0) {
319 | if ($value instanceof \DateTime) {
320 | $property = "_$name";
321 | $this->$property = $value;
322 | } else {
323 | throw new InvalidArgumentException("$nome need to be instance of DateTime");
324 | }
325 | } else {
326 | throw new Exception("property '$name' dont exists");
327 | }
328 | }
329 |
330 | public function getText()
331 | {
332 | $numero_sequencial = 1;
333 |
334 | $this->header->numero_sequencial = $numero_sequencial++;
335 |
336 | // valida os dados
337 | if (!$this->header->validate()) {
338 | throw new \InvalidArgumentException($this->header->last_error);
339 | }
340 |
341 | $dados = $this->header->getEncoded().self::QUEBRA_LINHA;
342 | $this->trailer = new Trailer($this);
343 | foreach ($this->detalhes as $detalhe) {
344 | $detalhe->numero_sequencial = $numero_sequencial++;
345 | if (!$detalhe->validate()) {
346 | throw new \InvalidArgumentException($detalhe->last_error);
347 | }
348 |
349 | $dados .= $detalhe->getEncoded().self::QUEBRA_LINHA;
350 | }
351 | $this->trailer->numero_sequencial = $numero_sequencial++;
352 |
353 | if (!$this->trailer->validate()) {
354 | throw new \InvalidArgumentException($this->trailer->last_error);
355 | }
356 |
357 | $dados .= $this->trailer->getEncoded().self::QUEBRA_LINHA;
358 |
359 | return $dados;
360 | }
361 |
362 | public function countDetalhes()
363 | {
364 | return count($this->detalhes);
365 | }
366 |
367 | public function save($filename)
368 | {
369 | $text = $this->getText();
370 | file_put_contents($filename, $text);
371 | }
372 | }
373 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab400/Detalhe.php:
--------------------------------------------------------------------------------
1 | codigo_banco;
10 | $yamlLoad = new \Cnab\Format\YamlLoad($codigo_banco);
11 | $yamlLoad->load($this, 'cnab400', 'remessa/detalhe');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab400/DetalheMulta.php:
--------------------------------------------------------------------------------
1 | codigo_banco;
10 | $yamlLoad = new \Cnab\Format\YamlLoad($codigo_banco);
11 | $yamlLoad->load($this, 'cnab400', 'remessa/detalhe_multa');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab400/Header.php:
--------------------------------------------------------------------------------
1 | codigo_banco;
10 | $yamlLoad = new \Cnab\Format\YamlLoad($codigo_banco);
11 | $yamlLoad->load($this, 'cnab400', 'remessa/header_arquivo');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/Cnab400/Trailer.php:
--------------------------------------------------------------------------------
1 | codigo_banco;
10 | $yamlLoad = new \Cnab\Format\YamlLoad($codigo_banco);
11 | $yamlLoad->load($this, 'cnab400', 'remessa/trailer_arquivo');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Cnab/Remessa/IArquivo.php:
--------------------------------------------------------------------------------
1 | filename = $filename;
24 | $this->layoutVersao = $layoutVersao;
25 |
26 | if (!file_exists($this->filename)) {
27 | throw new \Exception("Arquivo não encontrado: {$this->filename}");
28 | }
29 |
30 | $this->content = file_get_contents($this->filename);
31 |
32 | $this->codigo_banco = (int) $codigo_banco;
33 |
34 | $linhas = explode("\r\n", $this->content);
35 | if (count($linhas) < 2) {
36 | $linhas = explode("\n", $this->content);
37 | }
38 | $this->header = new HeaderArquivo($this);
39 | $this->trailer = new TrailerArquivo($this);
40 |
41 | $lastLote = null;
42 |
43 | $posLinha = 0;
44 |
45 | foreach ($linhas as $linha) {
46 | if (!trim($linha)) {
47 | continue;
48 | }
49 |
50 | $linhaRetorno = new Linha();
51 | $linhaRetorno->pos = $posLinha++;
52 | $linhaRetorno->texto = $linha;
53 |
54 | $this->linhas[] = $linhaRetorno;
55 |
56 | $tipo_registro = substr($linha, 7, 1);
57 | if ($tipo_registro == '0') {
58 | // header
59 | $this->header->loadFromString($linha);
60 | $linhaRetorno->linhaCnab = $this->header;
61 | } elseif ($tipo_registro == '1') {
62 | // header do lote
63 | if ($lastLote) {
64 | $this->lotes[] = $lastLote;
65 | }
66 | $lastLote = new Lote($this);
67 | $lastLote->header = new HeaderLote($this);
68 | $lastLote->header->loadFromString($linha);
69 |
70 | $linhaRetorno->linhaCnab = $lastLote->header;
71 | } elseif ($tipo_registro == '2') {
72 | // registros iniciais do lote (opcional)
73 | } elseif ($tipo_registro == '3') {
74 | // registros de detalhe - Segmentos
75 | if ($lastLote) {
76 | $linhaRetorno->linhaCnab = $lastLote->insertSegmento($linha);
77 | }
78 | } elseif ($tipo_registro == '4') {
79 | // registros finais do lote (opcional)
80 | } elseif ($tipo_registro == '5') {
81 | // registro trailer do lote
82 | $lastLote->trailer = new TrailerLote($this);
83 | $lastLote->trailer->loadFromString($linha);
84 | $this->lotes[] = $lastLote;
85 | $linhaRetorno->linhaCnab = $lastLote->trailer;
86 | $lastLote = null;
87 | } elseif ($tipo_registro == '9') {
88 | // trailer do arquivo
89 | $this->trailer->loadFromString($linha);
90 |
91 | $linhaRetorno->linhaCnab = $this->trailer;
92 | }
93 | }
94 | }
95 |
96 | public function listDetalhes()
97 | {
98 | $detalhes = array();
99 | foreach ($this->lotes as $lote) {
100 | foreach ($lote->listDetalhes() as $detalhe) {
101 | $detalhes[] = $detalhe;
102 | }
103 | }
104 |
105 | return $detalhes;
106 | }
107 |
108 | /**
109 | * Retorna o numero da conta.
110 | *
111 | * @return string
112 | */
113 | public function getConta()
114 | {
115 | return $this->header->getConta();
116 | }
117 |
118 | /**
119 | * Retorna o digito de auto conferencia da conta.
120 | *
121 | * @return string
122 | */
123 | public function getContaDac()
124 | {
125 | return $this->header->getContaDac();
126 | }
127 |
128 | /**
129 | * Retorna o codigo do banco.
130 | *
131 | * @return string
132 | */
133 | public function getCodigoBanco()
134 | {
135 | return $this->header->codigo_banco;
136 | }
137 |
138 | /**
139 | * Retorna a data de geração do arquivo.
140 | *
141 | * @return \DateTime
142 | */
143 | public function getDataGeracao()
144 | {
145 | $data_geracao_str = $this->header->data_geracao;
146 | $format = strlen($data_geracao_str) > 6 ? 'dmY' : 'dmy';
147 | $format_printf = strlen($data_geracao_str) > 6 ? '%08d' : '%06d';
148 |
149 | return $data_geracao_str ? \DateTime::createFromFormat($format, sprintf($format_printf, $data_geracao_str)) : false;
150 | }
151 |
152 | /**
153 | * Retorna o objeto DateTime da data crédito do arquivo
154 | * É melhor consultar no Detalhe a data de crédito, a caixa só informa no detalhe
155 | * (Esta função poderá ser removida, pois em alguns banco você só encontra esta data no detalhe).
156 | *
157 | * @return DateTime
158 | */
159 | public function getDataCredito()
160 | {
161 | $lote = $this->lotes[0];
162 | $header_lote = $lote->header;
163 |
164 | return $header_lote->data_credito ? \DateTime::createFromFormat('dmY', sprintf('%08d', $header_lote->data_credito)) : false;
165 | }
166 |
167 | public function getCodigoConvenio()
168 | {
169 | return $this->header->getCodigoConvenio();
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/Cnab240/Detalhe.php:
--------------------------------------------------------------------------------
1 | codigo_banco = $arquivo->codigo_banco;
17 | $this->arquivo = $arquivo;
18 | }
19 |
20 | /**
21 | * Retorno se é para dar baixa no boleto.
22 | *
23 | * @return bool
24 | */
25 | public function isBaixa()
26 | {
27 | $codigo_movimento = $this->segmento_t->codigo_movimento;
28 |
29 | return self::isBaixaStatic($codigo_movimento);
30 | }
31 |
32 | public static function isBaixaStatic($codigo_movimento)
33 | {
34 | $tipo_baixa = array(6, 9, 17, 25);
35 | $codigo_movimento = (int) $codigo_movimento;
36 | if (in_array($codigo_movimento, $tipo_baixa)) {
37 | return true;
38 | } else {
39 | return false;
40 | }
41 | }
42 |
43 | /**
44 | * Retorno se é uma baixa rejeitada.
45 | *
46 | * @return bool
47 | */
48 | public function isBaixaRejeitada()
49 | {
50 | $tipo_baixa = array(3, 26, 30);
51 | $codigo_movimento = (int) $this->segmento_t->codigo_movimento;
52 | if (in_array($codigo_movimento, $tipo_baixa)) {
53 | return true;
54 | } else {
55 | return false;
56 | }
57 | }
58 |
59 | /**
60 | * Identifica o tipo de detalhe, se por exemplo uma taxa de manutenção.
61 | *
62 | * @return int
63 | */
64 | public function getCodigo()
65 | {
66 | return (int) $this->segmento_t->codigo_movimento;
67 | }
68 |
69 | /**
70 | * Retorna o valor recebido em conta.
71 | *
72 | * @return float
73 | */
74 | public function getValorRecebido()
75 | {
76 | return $this->segmento_u->valor_liquido;
77 | }
78 |
79 | /**
80 | * Retorna o valor do título.
81 | *
82 | * @return float
83 | */
84 | public function getValorTitulo()
85 | {
86 | return $this->segmento_t->valor_titulo;
87 | }
88 |
89 | /**
90 | * Retorna o valor do pago.
91 | *
92 | * @return float
93 | */
94 | public function getValorPago()
95 | {
96 | return $this->segmento_u->valor_pago;
97 | }
98 |
99 | /**
100 | * Retorna o valor da tarifa.
101 | *
102 | * @return float
103 | */
104 | public function getValorTarifa()
105 | {
106 | return $this->segmento_t->valor_tarifa;
107 | }
108 |
109 | /**
110 | * Retorna o valor do Imposto sobre operações financeiras.
111 | *
112 | * @return float
113 | */
114 | public function getValorIOF()
115 | {
116 | return $this->segmento_u->valor_iof;
117 | }
118 |
119 | /**
120 | * Retorna o valor dos descontos concedido (antes da emissão).
121 | *
122 | * @return Double;
123 | */
124 | public function getValorDesconto()
125 | {
126 | return $this->segmento_u->valor_desconto;
127 | }
128 |
129 | /**
130 | * Retorna o valor dos abatimentos concedidos (depois da emissão).
131 | *
132 | * @return float
133 | */
134 | public function getValorAbatimento()
135 | {
136 | return $this->segmento_u->valor_abatimento;
137 | }
138 |
139 | /**
140 | * Retorna o valor de outras despesas.
141 | *
142 | * @return float
143 | */
144 | public function getValorOutrasDespesas()
145 | {
146 | return $this->segmento_u->valor_outras_despesas;
147 | }
148 |
149 | /**
150 | * Retorna o valor de outros creditos.
151 | *
152 | * @return float
153 | */
154 | public function getValorOutrosCreditos()
155 | {
156 | return $this->segmento_u->valor_outros_creditos;
157 | }
158 |
159 | /**
160 | * Retorna o número do documento do boleto.
161 | *
162 | * @return string
163 | */
164 | public function getNumeroDocumento()
165 | {
166 | $numero_documento = $this->segmento_t->numero_documento;
167 | if (trim($numero_documento, '0') == '') {
168 | return;
169 | }
170 |
171 | return $numero_documento;
172 | }
173 |
174 | /**
175 | * Retorna o nosso número do boleto.
176 | *
177 | * @return string
178 | */
179 | public function getNossoNumero()
180 | {
181 | $nossoNumero = $this->segmento_t->nosso_numero;
182 |
183 | if ($this->codigo_banco == 1) {
184 | $nossoNumero = preg_replace(
185 | '/^'.strval($this->arquivo->getCodigoConvenio()).'/',
186 | '',
187 | $nossoNumero
188 | );
189 | }
190 |
191 | if (in_array($this->codigo_banco, array(\Cnab\Banco::SANTANDER))) {
192 | // retira o dv
193 | $nossoNumero = substr($nossoNumero, 0, -1);
194 | }
195 |
196 | return $nossoNumero;
197 | }
198 |
199 | /**
200 | * Retorna o objeto \DateTime da data de vencimento do boleto.
201 | *
202 | * @return \DateTime
203 | */
204 | public function getDataVencimento()
205 | {
206 | $data = $this->segmento_t->data_vencimento ? \DateTime::createFromFormat('dmY', sprintf('%08d', $this->segmento_t->data_vencimento)) : false;
207 | if ($data) {
208 | $data->setTime(0, 0, 0);
209 | }
210 |
211 | return $data;
212 | }
213 |
214 | /**
215 | * Retorna a data em que o dinheiro caiu na conta.
216 | *
217 | * @return \DateTime
218 | */
219 | public function getDataCredito()
220 | {
221 | $data = $this->segmento_u->data_credito ? \DateTime::createFromFormat('dmY', sprintf('%08d', $this->segmento_u->data_credito)) : false;
222 | if ($data) {
223 | $data->setTime(0, 0, 0);
224 | }
225 |
226 | return $data;
227 | }
228 |
229 | /**
230 | * Retorna o valor de juros e mora.
231 | */
232 | public function getValorMoraMulta()
233 | {
234 | return $this->segmento_u->valor_acrescimos;
235 | }
236 |
237 | /**
238 | * Retorna a data da ocorrencia, o dia do pagamento.
239 | *
240 | * @return \DateTime
241 | */
242 | public function getDataOcorrencia()
243 | {
244 | $data = $this->segmento_u->data_ocorrencia ? \DateTime::createFromFormat('dmY', sprintf('%08d', $this->segmento_u->data_ocorrencia)) : false;
245 | if ($data) {
246 | $data->setTime(0, 0, 0);
247 | }
248 |
249 | return $data;
250 | }
251 |
252 | /**
253 | * Retorna o número da carteira do boleto.
254 | *
255 | * @return string
256 | */
257 | public function getCarteira()
258 | {
259 | if ($this->codigo_banco == 104) {
260 | /*
261 | É formado apenas o código da carteira
262 | Código da Carteira
263 | Código adotado pela FEBRABAN, para identificar a característica dos títulos dentro das modalidades de
264 | cobrança existentes no banco.
265 | ‘1’ = Cobrança Simples
266 | ‘3’ = Cobrança Caucionada
267 | ‘4’ = Cobrança Descontada
268 | O Código ‘1’ Cobrança Simples deve ser obrigatoriamente informado nas modalidades Cobrança Simples
269 | e Cobrança Rápida.
270 | */
271 | return;
272 | } elseif ($this->segmento_t->existField('carteira')) {
273 | return $this->segmento_t->carteira;
274 | } else {
275 | return;
276 | }
277 | }
278 |
279 | /**
280 | * Retorna o número da agencia do boleto.
281 | *
282 | * @return string
283 | */
284 | public function getAgencia()
285 | {
286 | return $this->segmento_t->agencia_mantenedora;
287 | }
288 |
289 | /**
290 | * Retorna o número da agencia do boleto.
291 | *
292 | * @return string
293 | */
294 | public function getAgenciaDv()
295 | {
296 | return $this->segmento_t->agencia_dv;
297 | }
298 |
299 | /**
300 | * Retorna a agencia cobradora.
301 | *
302 | * @return string
303 | */
304 | public function getAgenciaCobradora()
305 | {
306 | return $this->segmento_t->agencia_cobradora;
307 | }
308 |
309 | /**
310 | * Retorna a o dac da agencia cobradora.
311 | *
312 | * @return string
313 | */
314 | public function getAgenciaCobradoraDac()
315 | {
316 | return $this->segmento_t->agencia_cobradora_dac;
317 | }
318 |
319 | /**
320 | * Retorna o numero sequencial.
321 | *
322 | * @return Integer;
323 | */
324 | public function getNumeroSequencial()
325 | {
326 | return $this->segmento_t->numero_sequencial_lote;
327 | }
328 |
329 | /**
330 | * Retorna o nome do código.
331 | *
332 | * @return string
333 | */
334 | public function getCodigoNome()
335 | {
336 | $codigo = (int) $this->getCodigo();
337 |
338 | $table = array(
339 | 2 => 'Entrada Confirmada',
340 | 3 => 'Entrada Rejeitada',
341 | 4 => 'Transferência de Carteira/Entrada',
342 | 5 => 'Transferência de Carteira/Baixa',
343 | 6 => 'Liquidação',
344 | 9 => 'Baixa',
345 | 12 => 'Confirmação Recebimento Instrução de Abatimento',
346 | 13 => 'Confirmação Recebimento Instrução de Cancelamento Abatimento',
347 | 14 => 'Confirmação Recebimento Instrução Alteração de Vencimento',
348 | 17 => 'Liquidação Após Baixa ou Liquidação Título Não Registrado',
349 | 19 => 'Confirmação Recebimento Instrução de Protesto',
350 | 20 => 'Confirmação Recebimento Instrução de Sustação/Cancelamento de Protesto',
351 | 23 => 'Remessa a Cartório (Aponte em Cartório)',
352 | 24 => 'Retirada de Cartório e Manutenção em Carteira',
353 | 25 => 'Protestado e Baixado (Baixa por Ter Sido Protestado)',
354 | 26 => 'Instrução Rejeitada',
355 | 27 => 'Confirmação do Pedido de Alteração de Outros Dados',
356 | 28 => 'Débito de Tarifas/Custas',
357 | 30 => 'Alteração de Dados Rejeitada',
358 | 36 => 'Confirmação de envio de e-mail/SMS',
359 | 37 => 'Envio de e-mail/SMS rejeitado',
360 | 43 => 'Estorno de Protesto/Sustação',
361 | 44 => 'Estorno de Baixa/Liquidação',
362 | 45 => 'Alteração de dados',
363 | 51 => 'Título DDA reconhecido pelo sacado',
364 | 52 => 'Título DDA não reconhecido pelo sacado',
365 | 53 => 'Título DDA recusado pela CIP',
366 | );
367 |
368 | if (array_key_exists($codigo, $table)) {
369 | return $table[$codigo];
370 | } else {
371 | return 'Desconhecido';
372 | }
373 | }
374 |
375 | /**
376 | * Retorna o código de liquidação, normalmente usado para
377 | * saber onde o cliente efetuou o pagamento.
378 | *
379 | * @return string
380 | */
381 | public function getCodigoLiquidacao()
382 | {
383 | // @TODO: Resgatar o código de liquidação
384 | return;
385 | }
386 |
387 | /**
388 | * Retorna a descrição do código de liquidação, normalmente usado para
389 | * saber onde o cliente efetuou o pagamento.
390 | *
391 | * @return string
392 | */
393 | public function getDescricaoLiquidacao()
394 | {
395 | // @TODO: Resgator descrição do código de liquidação
396 | return;
397 | }
398 |
399 | public function dump()
400 | {
401 | $dump = PHP_EOL;
402 | $dump .= '== SEGMENTO T ==';
403 | $dump .= PHP_EOL;
404 | $dump .= $this->segmento_t->dump();
405 | $dump .= '== SEGMENTO U ==';
406 | $dump .= PHP_EOL;
407 | $dump .= $this->segmento_u->dump();
408 |
409 | if ($this->segmento_w) {
410 | $dump .= '== SEGMENTO W ==';
411 | $dump .= PHP_EOL;
412 | $dump .= $this->segmento_w->dump();
413 | }
414 |
415 | return $dump;
416 | }
417 |
418 | public function isDDA()
419 | {
420 | // @TODO: implementar funçao isDDA no Cnab240
421 | }
422 |
423 | public function getAlegacaoPagador()
424 | {
425 | // @TODO: implementar funçao getAlegacaoPagador no Cnab240
426 | }
427 | }
428 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/Cnab240/HeaderArquivo.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'header_arquivo');
11 | }
12 |
13 | public function getConta()
14 | {
15 | if ($this->existField('conta')) {
16 | return $this->conta;
17 | } else {
18 | return;
19 | }
20 | }
21 |
22 | public function getContaDac()
23 | {
24 | if ($this->existField('conta_dv')) {
25 | return $this->conta_dv;
26 | } else {
27 | return;
28 | }
29 | }
30 |
31 | public function getCodigoConvenio()
32 | {
33 | if ($this->existField('codigo_convenio')) {
34 | return $this->codigo_convenio;
35 | } else {
36 | return;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/Cnab240/HeaderLote.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'header_lote');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/Cnab240/Lote.php:
--------------------------------------------------------------------------------
1 | arquivo = $arquivo;
20 | $this->codigo_banco = $this->arquivo->codigo_banco;
21 | }
22 |
23 | public function insertSegmento($linha)
24 | {
25 | $codigo_segmento = strtoupper(substr($linha, 13, 1));
26 | $segmento = null;
27 | if ('T' == $codigo_segmento) {
28 | $segmento = new SegmentoT($this->arquivo);
29 | $segmento->loadFromString($linha);
30 | $this->lastDetalhe = new Detalhe($this->arquivo);
31 | $this->detalhes[] = $this->lastDetalhe;
32 | $this->lastDetalhe->segmento_t = $segmento;
33 | } elseif ('U' == $codigo_segmento) {
34 | $segmento = new SegmentoU($this->arquivo);
35 | $segmento->loadFromString($linha);
36 | if ($this->lastDetalhe) {
37 | $this->lastDetalhe->segmento_u = $segmento;
38 | }
39 | } elseif ('W' == $codigo_segmento) {
40 | $segmento = new SegmentoW($this->arquivo);
41 | $segmento->loadFromString($linha);
42 | if ($this->lastDetalhe) {
43 | $this->lastDetalhe->segmento_w = $segmento;
44 | }
45 | }
46 |
47 | return $segmento;
48 | }
49 |
50 | public function listDetalhes()
51 | {
52 | return $this->detalhes;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/Cnab240/SegmentoT.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'retorno/detalhe_segmento_t');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/Cnab240/SegmentoU.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'retorno/detalhe_segmento_u');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/Cnab240/SegmentoW.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'retorno/detalhe_segmento_w');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/Cnab240/TrailerArquivo.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'trailer_arquivo');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/Cnab240/TrailerLote.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab240', 'trailer_lote');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/Cnab400/Arquivo.php:
--------------------------------------------------------------------------------
1 | filename = $filename;
26 | $this->layoutVersao = $layoutVersao;
27 |
28 | if (!file_exists($this->filename)) {
29 | throw new Exception("Arquivo não encontrado: {$this->filename}");
30 | }
31 |
32 | $this->content = file_get_contents($this->filename);
33 |
34 | $this->codigo_banco = (int) $codigo_banco;
35 |
36 | $linhas = explode("\r\n", $this->content);
37 | if (count($linhas) < 2) {
38 | $linhas = explode("\n", $this->content);
39 | }
40 | $this->header = new Header($this);
41 | $this->trailer = new Trailer($this);
42 |
43 | $posLinha = 0;
44 |
45 | foreach ($linhas as $linha) {
46 | if (!trim($linha)) {
47 | continue;
48 | }
49 |
50 | $linhaRetorno = new Linha();
51 | $linhaRetorno->pos = $posLinha++;
52 | $linhaRetorno->texto = $linha;
53 |
54 | $this->linhas[] = $linhaRetorno;
55 |
56 | $tipo_registro = substr($linha, 0, 1);
57 |
58 | if ($tipo_registro == '0' && $linha) {
59 | $this->header->loadFromString($linha);
60 |
61 | $linhaRetorno->linhaCnab = $this->header;
62 | } elseif (in_array((int) $tipo_registro, array(1, 7))) {
63 | $detalhe = new Detalhe($this);
64 | $detalhe->loadFromString($linha);
65 | $this->detalhes[] = $detalhe;
66 |
67 | $linhaRetorno->linhaCnab = $detalhe;
68 | } elseif ($tipo_registro == '9') {
69 | $this->trailer->loadFromString($linha);
70 | $linhaRetorno->linhaCnab = $this->trailer;
71 | }
72 | }
73 | }
74 |
75 | public function listDetalhes()
76 | {
77 | return $this->detalhes;
78 | }
79 |
80 | /**
81 | * Retorna o numero da conta.
82 | *
83 | * @return string
84 | */
85 | public function getConta()
86 | {
87 | return $this->header->getConta();
88 | }
89 |
90 | /**
91 | * Retorna o código do cedente / código da empresa / código do convênio (cada banco chama de um nome).
92 | *
93 | * @return string
94 | */
95 | public function getCodigoCedente()
96 | {
97 | return $this->header->getCodigoCedente();
98 | }
99 |
100 | /**
101 | * Retorna o digito de auto conferencia da conta.
102 | *
103 | * @return string
104 | */
105 | public function getContaDac()
106 | {
107 | return $this->header->getContaDac();
108 | }
109 |
110 | /**
111 | * Retorna o codigo do banco.
112 | *
113 | * @return string
114 | */
115 | public function getCodigoBanco()
116 | {
117 | return $this->header->codigo_do_banco;
118 | }
119 |
120 | /**
121 | * Retorna a data de geração do arquivo.
122 | *
123 | * @return \DateTime
124 | */
125 | public function getDataGeracao()
126 | {
127 | $data = $this->header->data_de_geracao ? \DateTime::createFromFormat('dmy', sprintf('%06d', $this->header->data_de_geracao)) : false;
128 | if ($data) {
129 | $data->setTime(0, 0, 0);
130 | }
131 |
132 | return $data;
133 | }
134 |
135 | /**
136 | * Retorna o objeto DateTime da data crédito do arquivo
137 | * É melhor consultar no Detalhe a data de crédito, a caixa só informa no detalhe
138 | * (Esta função poderá ser removida, pois em alguns banco você só encontra esta data no detalhe).
139 | *
140 | * @return DateTime
141 | */
142 | public function getDataCredito()
143 | {
144 | if ($this->header->existField('data_de_credito')) {
145 | $data = $this->header->data_de_credito ? \DateTime::createFromFormat('dmy', sprintf('%06d', $this->header->data_de_credito)) : false;
146 | if ($data) {
147 | $data->setTime(0, 0, 0);
148 | }
149 |
150 | return $data;
151 | } else {
152 | return;
153 | }
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/Cnab400/Header.php:
--------------------------------------------------------------------------------
1 | _codigo_banco = $arquivo->codigo_banco;
12 | $yamlLoad = new \Cnab\Format\YamlLoad($arquivo->codigo_banco, $arquivo->layoutVersao);
13 | $yamlLoad->load($this, 'cnab400', 'retorno/header_arquivo');
14 | }
15 |
16 | public function getConta()
17 | {
18 | if ($this->existField('conta')) {
19 | return $this->conta;
20 | } elseif ($this->_codigo_banco == 104) {
21 | $codigo_cedente = sprintf('%016d', $this->codigo_cedente);
22 |
23 | return substr($codigo_cedente, 7, 8);
24 | }
25 | }
26 |
27 | public function getContaDac()
28 | {
29 | if ($this->existField('dac')) {
30 | return $this->dac;
31 | } elseif ($this->_codigo_banco == 104) {
32 | $codigo_cedente = sprintf('%016d', $this->codigo_cedente);
33 |
34 | return substr($codigo_cedente, 15, 1);
35 | }
36 | }
37 |
38 | public function getCodigoCedente()
39 | {
40 | if ($this->existField('codigo_cedente')) {
41 | return $this->codigo_cedente;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/Cnab400/Trailer.php:
--------------------------------------------------------------------------------
1 | codigo_banco, $arquivo->layoutVersao);
10 | $yamlLoad->load($this, 'cnab400', 'retorno/trailer_arquivo');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/CodigoOcorrencia.php:
--------------------------------------------------------------------------------
1 | loadFormat($format, 'retorno/codigo_ocorrencia');
17 |
18 | $codigo_banco = str_pad($codigo_banco, 3, '0', STR_PAD_LEFT);
19 |
20 | if (array_key_exists($codigo_banco, $array) && array_key_exists($codigo_ocorrencia, $array[$codigo_banco])) {
21 | return $array[$codigo_banco][$codigo_ocorrencia];
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Cnab/Retorno/IArquivo.php:
--------------------------------------------------------------------------------
1 | assertTrue(Banco::existBanco(Banco::ITAU));
12 | $this->assertTrue(Banco::existBanco(Banco::CEF));
13 | $this->assertTrue(Banco::existBanco(Banco::SANTANDER));
14 | $this->assertTrue(Banco::existBanco(Banco::BRADESCO));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/Cnab/Format/LinhaTest.php:
--------------------------------------------------------------------------------
1 | addField('codigo_banco', 1, 3, '9(3)', '000', array());
13 | $this->assertTrue($linha->existField('codigo_banco'));
14 | $this->assertFalse($linha->existField('codigo_branco'));
15 | $this->assertTrue($linha->validate());
16 | }
17 |
18 | /**
19 | * @depends testPodeAdicionarCampo
20 | */
21 | public function testPodeSubstituirCampo()
22 | {
23 | $linha = new Linha();
24 | $linha->addField('codigo_cedente_dv', 36, 36, '9(1)', '1', array());
25 | $linha->addField('uso_exclusivo_banco_01', 33, 40, 'X(8)', str_repeat(' ', 8), array());
26 | $this->assertFalse($linha->existField('codigo_cedente_dv'));
27 | $this->assertTrue($linha->existField('uso_exclusivo_banco_01'));
28 |
29 | $linha = new Linha();
30 | $linha->addField('codigo_banco', 1, 3, '9(3)', '000', array());
31 | $linha->addField('numero_lote', 4, 7, '9(4)', '000', array());
32 | $this->assertTrue($linha->existField('codigo_banco'));
33 | $this->assertTrue($linha->existField('numero_lote'));
34 |
35 | $linha->addField('codigo_banco', 1, 7, '9(7)', '00000000', array());
36 | $this->assertTrue($linha->existField('codigo_banco'));
37 | $this->assertTrue($linha->validate());
38 |
39 | $linha->addField('codigo_e_lote', 1, 7, '9(7)', '2', array());
40 | $this->assertTrue($linha->existField('codigo_e_lote'));
41 | $this->assertFalse($linha->existField('codigo_banco'));
42 | $this->assertFalse($linha->existField('numero_lote'));
43 | $this->assertTrue($linha->validate());
44 |
45 | return $linha;
46 | }
47 |
48 | /**
49 | * @depends testPodeSubstituirCampo
50 | */
51 | public function testPodeCodificarLinha($linha)
52 | {
53 | $linha->addField('teste', 8, 12, 'X(5)', 'teste', array());
54 |
55 | $encoded = $linha->getEncoded();
56 | $this->assertEquals(12, strlen($encoded));
57 | $this->assertEquals('0000002teste', $encoded);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/tests/Cnab/Format/PictureTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(200.00, Picture::decode('20000', '9(3)V9(2)', array()));
13 | $this->assertEquals(200.05, Picture::decode('20005', '9(3)V9(2)', array()));
14 | $this->assertEquals(2.5, Picture::decode('00250', '9(3)V9(2)', array()));
15 | $this->assertEquals(3.33, Picture::decode('0333', '9(2)V9(2)', array()));
16 |
17 | // integer number
18 | $this->assertEquals(200, Picture::decode('00200', '9(5)', array()));
19 | $this->assertEquals(3, Picture::decode('3', '9(1)', array()));
20 | $this->assertEquals(70.46, Picture::decode('07046', '9(3)V9(2)', array()));
21 |
22 | // big integer number
23 | $this->assertEquals('123456789123456', Picture::decode('000123456789123456', '9(15)', array()));
24 |
25 | // too big integer number
26 | $this->assertEquals('900000000048957', Picture::decode('900000000048957', '9(15)', array()));
27 |
28 | // string text
29 | $this->assertEquals(' Abc', Picture::decode(' Abc', 'X(5)', array()));
30 | $this->assertEquals('Abc', Picture::decode('Abc ', 'X(5)', array()));
31 | }
32 |
33 | public function testEncode()
34 | {
35 | // float number
36 | $this->assertEquals('20000', Picture::encode(200.00, '9(3)V9(2)', array()));
37 | $this->assertEquals('20005', Picture::encode(200.05, '9(3)V9(2)', array()));
38 | $this->assertEquals('20050', Picture::encode(200.50, '9(3)V9(2)', array()));
39 | $this->assertEquals('00250', Picture::encode(2.5, '9(3)V9(2)', array()));
40 | $this->assertEquals('00205', Picture::encode(2.05, '9(3)V9(2)', array()));
41 | $this->assertEquals('07046', Picture::encode(70.45999999999999, '9(3)V9(2)', array()));
42 | $this->assertEquals('07045', Picture::encode(70.45111111111111, '9(3)V9(2)', array()));
43 | $this->assertEquals('070451', Picture::encode(70.45111111111111, '9(3)V9(3)', array()));
44 |
45 | $linha = new \Cnab\Format\Linha();
46 | $field = new \Cnab\Format\Field($linha, 'valor_titulo', '9(3)V9(2)', 0, 4, array());
47 | $field->set(70.45999999999999);
48 | $this->assertEquals('07046', $field->getEncoded());
49 |
50 | // integer number
51 | $this->assertEquals('0200', Picture::encode(200, '9(4)', array()));
52 | $this->assertEquals('4', Picture::encode(4, '9(1)', array()));
53 |
54 | // big integer number
55 | $this->assertEquals('900000000048957', Picture::encode('900000000048957', '9(15)', array()));
56 |
57 | // string text
58 | $this->assertEquals('Abc ', Picture::encode('Abc', 'X(5)', array()));
59 | $this->assertEquals(' 123 ', Picture::encode(' 123', 'X(5)', array()));
60 |
61 | // encode date
62 | $data = new \DateTime('2003-02-01 00:00:00');
63 | $this->assertEquals('01022003', Picture::encode($data, '9(8)', array('date_format' => '%d%m%Y')));
64 |
65 | $data = new \DateTime('2009-08-07 01:02:03');
66 | $this->assertEquals('010203', Picture::encode($data, '9(8)', array('date_format' => '%H%M%S')));
67 | $this->assertEquals('030201', Picture::encode($data, '9(8)', array('date_format' => '%S%M%H')));
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/tests/Cnab/Format/YamlLoadTest.php:
--------------------------------------------------------------------------------
1 | array(
22 | 'pos' => array(1, 3),
23 | ),
24 | 'tipo_registro' => array(
25 | 'pos' => array(1, 4),
26 | ),
27 | );
28 |
29 | $yamlLoad->validateCollision($fields);
30 | }
31 |
32 | public function testNaoEmiteExceptionEmCamposSemColisao()
33 | {
34 | $yamlLoad = new YamlLoad(0);
35 |
36 | $fields1 = array(
37 | 'codigo_banco' => array(
38 | 'pos' => array(1, 3),
39 | ),
40 | 'tipo_registro' => array(
41 | 'pos' => array(4, 4),
42 | ),
43 | );
44 |
45 | $fields2 = array(
46 | 'codigo_banco' => array(
47 | 'pos' => array(1, 3),
48 | ),
49 | );
50 |
51 | $this->assertTrue($yamlLoad->validateCollision($fields1));
52 | $this->assertTrue($yamlLoad->validateCollision($fields2));
53 | }
54 |
55 | /**
56 | * @expectedException DomainException
57 | */
58 | public function testEmiteExceptionEmArrayMalformado()
59 | {
60 | $array = array(
61 | 'generic' => array(
62 | 'codigo_banco' => array(
63 | 'pos' => array(1, 3),
64 | 'picture' => '',
65 | ),
66 | 'tipo_registro' => array(
67 | 'pos' => array(4, 4),
68 | 'picture' => '',
69 | ),
70 | ),
71 | '033' => array(
72 | 'nome_empresa' => array(
73 | 'pos' => array(40, 80),
74 | 'picture' => '',
75 | ),
76 | 'numero_inscricao' => array(
77 | 'pos' => array(79, 80),
78 | 'picture' => '',
79 | ),
80 | ),
81 | );
82 |
83 | $yamlLoad = new YamlLoad(0);
84 | $yamlLoad->validateArray($array);
85 | }
86 |
87 | public function testNaoEmiteExceptionEmArrayValido()
88 | {
89 | $array = array(
90 | 'generic' => array(
91 | 'codigo_banco' => array(
92 | 'pos' => array(1, 3),
93 | 'picture' => '',
94 | ),
95 | 'tipo_registro' => array(
96 | 'pos' => array(4, 4),
97 | 'picture' => '',
98 | ),
99 | ),
100 | '033' => array(
101 | 'nome_empresa' => array(
102 | 'pos' => array(40, 80),
103 | 'picture' => '',
104 | ),
105 | 'numero_inscricao' => array(
106 | 'pos' => array(81, 81),
107 | 'picture' => '',
108 | ),
109 | ),
110 | );
111 |
112 | $yamlLoad = new YamlLoad(0);
113 | $this->assertTrue($yamlLoad->validateArray($array));
114 | }
115 |
116 | public function testBuscaFormatoGenericoEEspecifico()
117 | {
118 | $yamlLoad = $this->getMockBuilder('\Cnab\Format\YamlLoad')
119 | ->setMethods(array('loadYaml'))
120 | ->setConstructorArgs(array(33))
121 | ->getMock();
122 |
123 | $testFormat = array(
124 | 'codigo_banco' => array(
125 | 'pos' => array(1, 3),
126 | 'picture' => '9(3)',
127 | ),
128 | );
129 |
130 | $yamlLoad->expects($this->at(0))
131 | ->method('loadYaml')
132 | ->with(
133 | $this->equalTo($yamlLoad->formatPath.'/cnab240/generic/header_lote.yml')
134 | )
135 | ->will($this->returnValue($testFormat));
136 |
137 | $yamlLoad->expects($this->at(1))
138 | ->method('loadYaml')
139 | ->with(
140 | $this->equalTo($yamlLoad->formatPath.'/cnab240/033/header_lote.yml')
141 | )
142 | ->will($this->returnValue($testFormat));
143 |
144 | $linha = new Linha();
145 | $yamlLoad->load($linha, 'cnab240', 'header_lote');
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/tests/Cnab/Remessa/Cnab240/BancoDoBrasilTest.php:
--------------------------------------------------------------------------------
1 | markTestIncomplete('A versão do layout foi alterada de 020 para 030, porém não ainda está em beta e não foram feitos testes para a nova versão');
10 |
11 | $codigoBanco = \Cnab\Banco::BANCO_DO_BRASIL;
12 | $cnabFactory = new \Cnab\Factory();
13 | $arquivo = $cnabFactory->createRemessa($codigoBanco, 'cnab240');
14 | $arquivo->configure(array(
15 | 'data_geracao' => new \DateTime('2015-02-01 01:02:03'),
16 | 'data_gravacao' => new \DateTime('2015-02-01'),
17 | 'nome_fantasia' => 'Nome Fantasia da sua empresa',
18 | 'razao_social' => 'Razão social da sua empresa',
19 | 'cnpj' => '11222333444455',
20 | 'banco' => $codigoBanco, //código do banco
21 | 'logradouro' => 'Logradouro da Sua empresa',
22 | 'numero' => 'Número do endereço',
23 | 'bairro' => 'Bairro da sua empresa',
24 | 'cidade' => 'Cidade da sua empresa',
25 | 'uf' => 'SP',
26 | 'cep' => '00000111',
27 | 'conta' => '123456',
28 | 'conta_dv' => '5',
29 | 'operacao' => '012',
30 | 'agencia' => '1234',
31 | 'agencia_dv' => '3',
32 | 'codigo_convenio' => '123123',
33 | 'codigo_carteira' => '11', // número da carteira
34 | 'variacao_carteira' => '345',
35 | 'numero_sequencial_arquivo' => 1,
36 | ));
37 |
38 | // você pode adicionar vários boletos em uma remessa
39 | $arquivo->insertDetalhe(array(
40 | 'codigo_ocorrencia' => 1, // 1 = Entrada de título, futuramente poderemos ter uma constante
41 | 'nosso_numero' => '12345',
42 | 'numero_documento' => '12345678',
43 | 'carteira' => '11',
44 | 'codigo_carteira' => \Cnab\CodigoCarteira::COBRANCA_SIMPLES,
45 | 'especie' => \Cnab\Especie::BB_DUPLICATA_MERCANTIL, // Você pode consultar as especies Cnab\Especie::CEF_OUTROS, futuramente poderemos ter uma tabela na documentação
46 | 'aceite' => 'N', // "S" ou "N"
47 | 'registrado' => false,
48 | 'valor' => 100.39, // Valor do boleto
49 | 'instrucao1' => '', // 1 = Protestar com (Prazo) dias, 2 = Devolver após (Prazo) dias, futuramente poderemos ter uma constante
50 | 'instrucao2' => '', // preenchido com zeros
51 | 'sacado_razao_social' => 'Nome do cliente', // O Sacado é o cliente, preste atenção nos campos abaixo
52 | 'sacado_tipo' => 'cnpj', //campo fixo, escreva 'cpf' (sim as letras cpf) se for pessoa fisica, cnpj se for pessoa juridica
53 | 'sacado_cnpj' => '21.222.333.4444-55',
54 | 'sacado_logradouro' => 'Logradouro do cliente',
55 | 'sacado_bairro' => 'Bairro do cliente',
56 | 'sacado_cep' => '00000-111',
57 | 'sacado_cidade' => 'Cidade do cliente',
58 | 'sacado_uf' => 'BA',
59 | 'data_vencimento' => new \DateTime('2015-02-03'),
60 | 'data_cadastro' => new \DateTime('2015-01-14'),
61 | 'codigo_juros_mora' => 2, //‘1’ = Valor por Dia, ‘2’ = Taxa Mensal, ‘3’ = Isento
62 | 'juros_de_um_dia' => 0.10, // Valor de 1 dia ou taxa do juros de 1 mês
63 | 'data_desconto' => new \DateTime('2015-02-09'),
64 | 'valor_desconto' => 10.0, // Valor do desconto
65 | 'prazo' => 10, // prazo de dias para o cliente pagar após o vencimento
66 | 'taxa_de_permanencia' => '0', //00 = Acata Comissão por Dia (recomendável), 51 Acata Condições de Cadastramento na CAIXA
67 | 'mensagem' => 'Descrição do boleto',
68 | 'data_multa' => new \DateTime('2015-02-07'), // data da multa
69 | 'valor_multa' => 11.2, // valor da multa
70 | 'baixar_apos_dias' => 30,
71 | 'dias_iniciar_contagem_juros' => 1,
72 | ));
73 |
74 | $texto = $arquivo->getText();
75 | $lines = explode("\r\n", trim($texto, "\r\n"));
76 |
77 | $this->assertEquals(7, count($lines));
78 |
79 | $headerArquivoText = $lines[0];
80 | $headerLoteText = $lines[1];
81 | $segmentoPText = $lines[2];
82 | $segmentoQText = $lines[3];
83 | $segmentoRText = $lines[4];
84 | $trailerLoteText = $lines[5];
85 | $trailerArquivoText = $lines[6];
86 |
87 | $asserts = array(
88 | 'headerArquivo' => array(
89 | '1:3' => '001', // codigo_banco
90 | '4:7' => '0000', // lote_servico
91 | '8:8' => '0', // tipo_registro
92 | '9:17' => ' ', // uso_exclusivo_febraban_01
93 | '18:18' => '2', // codigo_inscricao
94 | '19:32' => '11222333444455', // numero_inscricao
95 | '33:41' => '000123123', // codigo convenio
96 | '42:45' => '0014', // Cobrança Cedende BB: Informar 0014 para cobrança cedente
97 | '46:47' => '11', // Carteira
98 | '48:50' => '345', // Variação carteira
99 | '51:52' => ' ', // uso reservado bb
100 | '53:57' => '01234', // agencia
101 | '58:58' => '3', // agencia_dv
102 | '59:70' => '000000123456', // conta
103 | '71:71' => '5', // conta dv
104 | '72:72' => ' ', // campo não tratado pelo bb
105 | '73:102' => 'Nome Fantasia da sua empresa ', // nome_empresa
106 | '103:132' => 'BANCO DO BRASIL S.A. ', // nome_banco
107 | '133:142' => ' ', // uso_exclusivo_febraban_02
108 | '143:143' => '1', // codigo_remessa_retorno
109 | '144:151' => '01022015', // data_geracao
110 | '152:157' => '010203', // hora_geracao
111 | '158:163' => '000001', // numero_sequencial_arquivo
112 | '164:166' => '030', // versao_layout_arquivo
113 | '167:171' => '00000', // densidade_gravacao_arquivo
114 | '172:191' => ' ', // Para Uso Reservado do Banco
115 | '192:211' => 'REMESSA-PRODUCAO ', // Para Uso Reservado da Empresa
116 | '212:225' => ' ', // Uso Exclusivo FEBRABAN / CNAB
117 | '226:240' => '0000000000000000', // Uso Exclusivo FEBRABAN / CNAB
118 | ),
119 | 'headerLote' => array(
120 | '1:3' => '001', // codigo_banco
121 | '4:7' => '0001', // lote_servico
122 | '8:8' => '1', // tipo_registro
123 | '9:9' => 'R', // tipo_operacao
124 | '10:11' => '01', // tipo_servico
125 | '12:13' => '00', // Uso Exclusivo FEBRABAN/CNAB
126 | '14:16' => '030', // versao_layout_lote
127 | '17:17' => ' ', // uso_exclusivo_febraban_01
128 | '18:18' => '2', // codigo_inscricao
129 | '19:33' => '011222333444455', // numero_inscricao
130 | '34:42' => '000123123', // codigo_convenio
131 | '43:46' => '0014', // Cobrança cedente, Informar 0014 para cobrança
132 | '47:48' => '11', // carteira
133 | '49:51' => '345', // variaçã carteira
134 | '52:53' => ' ', // Use TS para testes
135 | '54:58' => '01234', // agencia
136 | '59:59' => '3', // agencia_dv
137 | '60:71' => '000000123456', // conta
138 | '72:72' => '5', // conta dv
139 | '73:73' => ' ', // uso_exclusivo_banco_02
140 | '74:103' => 'Nome Fantasia da sua empresa ', // nome_empresa
141 | '104:143' => ' ', // mensagem_1
142 | '144:183' => ' ', // mensagem_2
143 | '184:191' => '00000001', // numero_sequencial_arquivo
144 | '192:199' => '01022015', // data_geracao
145 | '200:207' => '00000000', // data_credito
146 | '208:240' => ' ', // uso_exclusivo_febraban_02
147 | ),
148 | 'segmentoP' => array(
149 | '1:3' => '001', // codigo_banco
150 | '4:7' => '0001', // lote_servico
151 | '8:8' => '3', // tipo_registro
152 | '9:13' => '00001', // numero_sequencial_lote
153 | '14:14' => 'P', // codigo_segmento
154 | '15:15' => ' ', // uso_exclusivo_febraban_01
155 | '16:17' => '01', // codigo_ocorrencia
156 | '18:22' => '01234', // agencia
157 | '23:23' => '3', // agencia_dv
158 | '24:35' => '000000123456', // número da conta
159 | '36:36' => '5', // conta dv
160 | '37:37' => ' ', // Dígito Verificador da Ag/Conta (Não usado pelo BB)
161 | '38:57' => '123123123459 ', // nosso_numero
162 | '58:58' => '1', // codigo_carteira
163 | '59:59' => '2', // forma_cadastramento
164 | '60:60' => '2', // tipo_documento
165 | '61:61' => '2', // identificacao_emissao
166 | '62:62' => '2', // identificacao_distribuicao
167 | '63:77' => '12345678 ', // numero_documento
168 | '78:85' => '03022015', // vencimento
169 | '86:100' => '000000000010039', // valor_titulo
170 | '101:105' => '00000', // agencia_cobradora
171 | '106:106' => '0', // agencia_cobradora_dv
172 | '107:108' => '02', // especie
173 | '109:109' => 'N', // aceite
174 | '110:117' => '14012015', // data_emissao
175 | '118:118' => '1', // codigo_juros_mora
176 | '119:126' => '04022015', // data_juros_mora
177 | '127:141' => '000000000000010', // valor_juros_mora
178 | '142:142' => '1', // codigo_desconto_1
179 | '143:150' => '09022015', // data_desconto_1
180 | '151:165' => '000000000001000', // valor_desconto_1
181 | '166:180' => '000000000000000', // valor_iof
182 | '181:195' => '000000000000000', // valor_abatimento
183 | '196:220' => '12345678 ', // uso_empresa
184 | '221:221' => '3', // codigo_protesto
185 | '222:223' => '00', // prazo_protesto
186 | '224:224' => '0', // codigo_baixa
187 | '225:227' => '000', // prazo_baixa
188 | '228:229' => '09', // codigo_moeda
189 | '230:239' => '0000000000', // uso_exclusivo_banco_03
190 | '240:240' => ' ', // uso_exclusivo_febraban_02
191 | ),
192 | 'segmentoQ' => array(
193 | '1:3' => '001', // codigo_banco
194 | '4:7' => '0001', // lote_servico
195 | '8:8' => '3', // tipo_registro
196 | '9:13' => '00002', // numero_sequencial_lote
197 | '14:14' => 'Q', // codigo_segmento
198 | '15:15' => ' ', // uso_exclusivo_febraban_01
199 | '16:17' => '01', // codigo_ocorrencia
200 | '18:18' => '2', // sacado_codigo_inscricao
201 | '19:33' => '021222333444455', // sacado_numero_inscricao
202 | '34:73' => 'NOME DO CLIENTE ', // nome
203 | '74:113' => 'LOGRADOURO DO CLIENTE ', // logradouro
204 | '114:128' => 'BAIRRO DO CLIEN', // bairro
205 | '129:136' => '00000111', // cep
206 | '137:151' => 'CIDADE DO CLIEN', // cidade
207 | '152:153' => 'BA', // estado
208 | '154:154' => '2', // sacador_codigo_inscricao
209 | '155:169' => '011222333444455', // sacador_numero_inscricao
210 | '170:209' => 'Nome Fantasia da sua empresa ', // sacador_nome
211 | '210:212' => ' ', // uso_exclusivo_febraban_02
212 | '213:232' => ' ', // uso_exclusivo_febraban_03
213 | '233:240' => ' ', // uso_exclusivo_febraban_04
214 | ),
215 | 'segmentoR' => array(
216 | '1:3' => '001', // codigo_banco
217 | '4:7' => '0001', // lote_servico
218 | '8:8' => '3', // tipo_registro
219 | '9:13' => '00003', // numero_sequencial_lote
220 | '14:14' => 'R', // codigo_segmento
221 | '15:15' => ' ', // uso_exclusivo_febraban_01
222 | '16:17' => '01', // codigo_ocorrencia
223 |
224 | // campos não tratado pelo banco do brasil
225 | '18:65' => ' ', // uso_exclusivo_febraban_02
226 |
227 | '66:66' => '1', // codigo_multa
228 | '67:74' => '07022015', // data_multa
229 | '75:89' => '000000000001120', // valor_multa
230 | '90:99' => ' ', // informacao_sacado
231 | '100:139' => ' ', // mensagem_3
232 | '140:179' => ' ', // mensagem_4
233 | '180:240' => ' ', // uso_exclusivo_febraban_03
234 | ),
235 | 'trailerLote' => array(
236 | '1:3' => '001', // codigo_banco
237 | '4:7' => '0001', // lote_servico
238 | '8:8' => '5', // tipo_registro
239 | '18:23' => '000005', // qtde_registro_lote
240 | '24:240' => str_repeat(' ', 217), // uso_exclusivo_febraban_02
241 | ),
242 | 'trailerArquivo' => array(
243 | '1:3' => '001', // codigo_banco
244 | '4:7' => '9999', // lote_servico
245 | '8:8' => '9', // tipo_registro
246 | '9:17' => ' ', // uso_exclusivo_febraban01
247 | '18:23' => '000001', // qtde_lotes
248 | '24:29' => '000007', // qtde_registros
249 | '30:35' => ' ', // uso_exclusivo_febraban02
250 | '36:240' => ' ', // uso_exclusivo_febraban_03
251 | ),
252 | );
253 |
254 | foreach ($asserts as $tipo => $campos) {
255 | $vname = "{$tipo}Text";
256 | foreach ($campos as $pos => $value) {
257 | $aux = explode(':', $pos);
258 | $start = $aux[0] - 1;
259 | $end = ($aux[1] - $aux[0]) + 1;
260 | $this->assertEquals($value, substr($$vname, $start, $end), "[ ] Campo $pos do $tipo");
261 | }
262 | }
263 | }
264 | }
265 |
--------------------------------------------------------------------------------
/tests/Cnab/Remessa/Cnab240/CaixaTest.php:
--------------------------------------------------------------------------------
1 | createRemessa($codigoBanco, 'cnab240', 'sigcb');
12 | $arquivo->configure(array(
13 | 'data_geracao' => new \DateTime('2015-02-01 01:02:03'),
14 | 'data_gravacao' => new \DateTime('2015-02-01'),
15 | 'nome_fantasia' => 'Nome Fantasia da sua empresa',
16 | 'razao_social' => 'Razão social da sua empresa',
17 | 'cnpj' => '11222333444455',
18 | 'banco' => $codigoBanco, //código do banco
19 | 'logradouro' => 'Logradouro da Sua empresa',
20 | 'numero' => 'Número do endereço',
21 | 'bairro' => 'Bairro da sua empresa',
22 | 'cidade' => 'Cidade da sua empresa',
23 | 'uf' => 'SP',
24 | 'cep' => '00000111',
25 | 'conta' => '123456',
26 | 'operacao' => '012',
27 | 'agencia' => '1234',
28 | 'agencia_dv' => '3',
29 | 'codigo_cedente' => '123123',
30 | 'numero_sequencial_arquivo' => 1,
31 | ));
32 |
33 | // você pode adicionar vários boletos em uma remessa
34 | $arquivo->insertDetalhe(array(
35 | 'codigo_ocorrencia' => 1, // 1 = Entrada de título, futuramente poderemos ter uma constante
36 | 'nosso_numero' => '12345679',
37 | 'numero_documento' => '12345678',
38 | 'carteira' => '111',
39 | 'especie' => \Cnab\Especie::CNAB240_OUTROS, // Você pode consultar as especies Cnab\Especie::CEF_OUTROS, futuramente poderemos ter uma tabela na documentação
40 | 'aceite' => 'N', // "S" ou "N"
41 | 'registrado' => false,
42 | 'modalidade_carteira' => '21',
43 | 'valor' => 100.39, // Valor do boleto
44 | 'instrucao1' => '', // 1 = Protestar com (Prazo) dias, 2 = Devolver após (Prazo) dias, futuramente poderemos ter uma constante
45 | 'instrucao2' => '', // preenchido com zeros
46 | 'sacado_razao_social' => 'Nome do cliente', // O Sacado é o cliente, preste atenção nos campos abaixo
47 | 'sacado_tipo' => 'cnpj', //campo fixo, escreva 'cpf' (sim as letras cpf) se for pessoa fisica, cnpj se for pessoa juridica
48 | 'sacado_cnpj' => '21.222.333.4444-55',
49 | 'sacado_logradouro' => 'Logradouro do cliente',
50 | 'sacado_bairro' => 'Bairro do cliente',
51 | 'sacado_cep' => '00000-111',
52 | 'sacado_cidade' => 'Cidade do cliente',
53 | 'sacado_uf' => 'BA',
54 | 'data_vencimento' => new \DateTime('2015-02-03'),
55 | 'data_cadastro' => new \DateTime('2015-01-14'),
56 | 'juros_de_um_dia' => 0.10, // Valor do juros de 1 dia'
57 | 'data_desconto' => new \DateTime('2015-02-09'),
58 | 'valor_desconto' => 10.0, // Valor do desconto
59 | 'prazo' => 10, // prazo de dias para o cliente pagar após o vencimento
60 | 'taxa_de_permanencia' => '0', //00 = Acata Comissão por Dia (recomendável), 51 Acata Condições de Cadastramento na CAIXA
61 | 'mensagem' => 'Descrição do boleto',
62 | 'data_multa' => new \DateTime('2015-02-07'), // data da multa
63 | 'valor_multa' => 11.2, // valor da multa
64 | 'baixar_apos_dias' => 30,
65 | 'dias_iniciar_contagem_juros' => 1,
66 | ));
67 |
68 | $texto = $arquivo->getText();
69 | $lines = explode("\r\n", trim($texto, "\r\n"));
70 |
71 | $this->assertEquals(7, count($lines));
72 |
73 | $headerArquivoText = $lines[0];
74 | $headerLoteText = $lines[1];
75 | $segmentoPText = $lines[2];
76 | $segmentoQText = $lines[3];
77 | $segmentoRText = $lines[4];
78 | $trailerLoteText = $lines[5];
79 | $trailerArquivoText = $lines[6];
80 |
81 | $asserts = array(
82 | 'headerArquivo' => array(
83 | '1:3' => '104', // codigo_banco
84 | '4:7' => '0000', // lote_servico
85 | '8:8' => '0', // tipo_registro
86 | '9:17' => ' ', // uso_exclusivo_febraban_01
87 | '18:18' => '2', // codigo_inscricao
88 | '19:32' => '11222333444455', // numero_inscricao
89 | '33:52' => '00000000000000000000', // uso exclusivo caixa
90 | '53:57' => '01234', // agencia
91 | '58:58' => '3', // agencia_dv
92 | '59:64' => '123123', // codigo_cedente
93 | '65:71' => '0000000', // uso_exclusivo_caixa_02
94 | '72:72' => '0', // uso_exclusivo_caixa_03
95 | '73:102' => 'Nome Fantasia da sua empresa ', // nome_empresa
96 | '103:132' => 'CAIXA ECONOMICA FEDERAL ', // nome_banco
97 | '133:142' => ' ', // uso_exclusivo_febraban_02
98 | '143:143' => '1', // codigo_remessa_retorno
99 | '144:151' => '01022015', // data_geracao
100 | '152:157' => '010203', // hora_geracao
101 | '158:163' => '000001', // numero_sequencial_arquivo
102 | '164:166' => '050', // versao_layout_arquivo
103 | '167:171' => '00000', // densidade_gravacao_arquivo
104 | '172:191' => ' ', // uso_reservado_banco
105 | '192:211' => 'REMESSA-PRODUCAO ', // uso_reservado_empresa
106 | '212:215' => ' ', // versao_aplicativo_caixa
107 | '216:240' => ' ', // uso_exclusivo_febraban_03
108 | ),
109 | 'headerLote' => array(
110 | '1:3' => '104', // codigo_banco
111 | '4:7' => '0001', // lote_servico
112 | '8:8' => '1', // tipo_registro
113 | '9:9' => 'R', // tipo_operacao
114 | '10:11' => '02', // tipo_servico
115 | '12:13' => '00', // forma_lancamento
116 | '14:16' => '030', // versao_layout_lote
117 | '17:17' => ' ', // uso_exclusivo_febraban_01
118 | '18:18' => '2', // codigo_inscricao
119 | '19:33' => '011222333444455', // numero_inscricao
120 | '34:39' => '123123', // codigo_convenio
121 | '40:53' => '00000000000000', // uso_exclusivo_banco
122 | '54:58' => '01234', // agencia
123 | '59:59' => '3', // agencia_dv
124 | '60:65' => '123123', // codigo_cedente
125 | '66:72' => '0000000', // codigo_modelo
126 | '73:73' => '0', // uso_exclusivo_banco_02
127 | '74:103' => 'Nome Fantasia da sua empresa ', // nome_empresa
128 | '104:143' => ' ', // mensagem_1
129 | '144:183' => ' ', // mensagem_2
130 | '184:191' => '00000001', // numero_sequencial_arquivo
131 | '192:199' => '01022015', // data_geracao
132 | '200:207' => '00000000', // data_credito
133 | '208:240' => ' ', // uso_exclusivo_febraban_02
134 | ),
135 | 'segmentoP' => array(
136 | '1:3' => '104', // codigo_banco
137 | '4:7' => '0001', // lote_servico
138 | '8:8' => '3', // tipo_registro
139 | '9:13' => '00001', // numero_sequencial_lote
140 | '14:14' => 'P', // codigo_segmento
141 | '15:15' => ' ', // uso_exclusivo_febraban_01
142 | '16:17' => '01', // codigo_ocorrencia
143 | '18:22' => '01234', // agencia
144 | '23:23' => '3', // agencia_dv
145 | '24:29' => '123123', // codigo_cedente
146 | '30:37' => '00000000', // uso_exclusivo_caixa_01
147 | '38:40' => '000', // uso_exclusivo_caixa_02
148 | '41:42' => '21', // modalidade_carteira
149 | '43:57' => '000000012345679', // nosso_numero
150 | '58:58' => '1', // codigo_carteira
151 | '59:59' => '2', // forma_cadastramento
152 | '60:60' => '2', // tipo_documento
153 | '61:61' => '2', // identificacao_emissao
154 | '62:62' => '2', // identificacao_distribuicao
155 | '63:73' => '12345678 ', // numero_documento
156 | '74:77' => ' ', // uso_exclusivo_banco_02
157 | '78:85' => '03022015', // vencimento
158 | '86:100' => '000000000010039', // valor_titulo
159 | '101:105' => '00000', // agencia_cobradora
160 | '106:106' => '0', // agencia_cobradora_dv
161 | '107:108' => '99', // especie
162 | '109:109' => 'N', // aceite
163 | '110:117' => '14012015', // data_emissao
164 | '118:118' => '1', // codigo_juros_mora
165 | '119:126' => '04022015', // data_juros_mora
166 | '127:141' => '000000000000010', // valor_juros_mora
167 | '142:142' => '1', // codigo_desconto_1
168 | '143:150' => '09022015', // data_desconto_1
169 | '151:165' => '000000000001000', // valor_desconto_1
170 | '166:180' => '000000000000000', // valor_iof
171 | '181:195' => '000000000000000', // valor_abatimento
172 | '196:220' => '12345678 ', // uso_empresa
173 | '221:221' => '3', // codigo_protesto
174 | '222:223' => '00', // prazo_protesto
175 | '224:224' => '1', // codigo_baixa
176 | '225:227' => '030', // prazo_baixa
177 | '228:229' => '09', // codigo_moeda
178 | '230:239' => '0000000000', // uso_exclusivo_banco_03
179 | '240:240' => ' ', // uso_exclusivo_febraban_02
180 | ),
181 | 'segmentoQ' => array(
182 | '1:3' => '104', // codigo_banco
183 | '4:7' => '0001', // lote_servico
184 | '8:8' => '3', // tipo_registro
185 | '9:13' => '00002', // numero_sequencial_lote
186 | '14:14' => 'Q', // codigo_segmento
187 | '15:15' => ' ', // uso_exclusivo_febraban_01
188 | '16:17' => '01', // codigo_ocorrencia
189 | '18:18' => '2', // sacado_codigo_inscricao
190 | '19:33' => '021222333444455', // sacado_numero_inscricao
191 | '34:73' => 'NOME DO CLIENTE ', // nome
192 | '74:113' => 'LOGRADOURO DO CLIENTE ', // logradouro
193 | '114:128' => 'BAIRRO DO CLIEN', // bairro
194 | '129:136' => '00000111', // cep
195 | '137:151' => 'CIDADE DO CLIEN', // cidade
196 | '152:153' => 'BA', // estado
197 | '154:154' => '2', // sacador_codigo_inscricao
198 | '155:169' => '011222333444455', // sacador_numero_inscricao
199 | '170:209' => 'Nome Fantasia da sua empresa ', // sacador_nome
200 | '210:212' => ' ', // uso_exclusivo_febraban_02
201 | '213:232' => ' ', // uso_exclusivo_febraban_03
202 | '233:240' => ' ', // uso_exclusivo_febraban_04
203 | ),
204 | 'segmentoR' => array(
205 | '1:3' => '104', // codigo_banco
206 | '4:7' => '0001', // lote_servico
207 | '8:8' => '3', // tipo_registro
208 | '9:13' => '00003', // numero_sequencial_lote
209 | '14:14' => 'R', // codigo_segmento
210 | '15:15' => ' ', // uso_exclusivo_febraban_01
211 | '16:17' => '01', // codigo_ocorrencia
212 | '18:65' => '000000000000000000000000000000000000000000000000', // uso_exclusivo_febraban_02
213 | '66:66' => '1', // codigo_multa
214 | '67:74' => '07022015', // data_multa
215 | '75:89' => '000000000001120', // valor_multa
216 | '90:99' => ' ', // informacao_sacado
217 | '100:139' => ' ', // mensagem_3
218 | '140:179' => ' ', // mensagem_4
219 | '180:240' => ' ', // uso_exclusivo_febraban_03
220 | ),
221 | 'trailerLote' => array(
222 | '1:3' => '104', // codigo_banco
223 | '4:7' => '0001', // lote_servico
224 | '8:8' => '5', // tipo_registro
225 | '18:23' => '000005', // qtde_registro_lote
226 | '24:29' => '000001', // qtde_titulo_cobranca_simples
227 | '30:46' => '00000000000010039', // valor_total_titulo_simples
228 | '93:123' => ' ', // uso_exclusivo_febraban_02
229 | '124:240' => ' ', // uso_exclusivo_febraban_03
230 | '47:52' => '000000', // qtde_titulo_cobranca_caucionada
231 | '53:69' => '00000000000000000', // valor_total_titulo_caucionada
232 | '9:17' => ' ', // uso_exclusivo_febraban_01
233 | '70:75' => '000000', // qtde_titulo_cobranca_descontada
234 | '76:92' => '00000000000000000', // valor_total_titulo_descontada
235 | ),
236 | 'trailerArquivo' => array(
237 | '1:3' => '104', // codigo_banco
238 | '4:7' => '9999', // lote_servico
239 | '8:8' => '9', // tipo_registro
240 | '9:17' => ' ', // uso_exclusivo_febraban01
241 | '18:23' => '000001', // qtde_lotes
242 | '24:29' => '000007', // qtde_registros
243 | '30:35' => ' ', // uso_exclusivo_febraban02
244 | '36:240' => ' ', // uso_exclusivo_febraban_03
245 | ),
246 | );
247 |
248 | foreach ($asserts as $tipo => $campos) {
249 | $vname = "{$tipo}Text";
250 | foreach ($campos as $pos => $value) {
251 | $aux = explode(':', $pos);
252 | $start = $aux[0] - 1;
253 | $end = ($aux[1] - $aux[0]) + 1;
254 | $this->assertEquals($value, substr($$vname, $start, $end), "[ ] Campo $pos do $tipo");
255 | }
256 | }
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/tests/Cnab/Remessa/Cnab400/ArquivoTest.php:
--------------------------------------------------------------------------------
1 | configure(array(
12 | 'data_geracao' => new \DateTime('2015-02-01'),
13 | 'data_gravacao' => new \DateTime('2015-02-01'),
14 | 'nome_fantasia' => 'Nome Fantasia da sua empresa',
15 | 'razao_social' => 'Razão social da sua empresa',
16 | 'cnpj' => '11222333444455',
17 | 'banco' => $codigo_banco, //código do banco
18 | 'logradouro' => 'Logradouro da Sua empresa',
19 | 'numero' => 'Número do endereço',
20 | 'bairro' => 'Bairro da sua empresa',
21 | 'cidade' => 'Cidade da sua empresa',
22 | 'uf' => 'SP',
23 | 'cep' => '00000111',
24 | 'agencia' => '1234',
25 | 'conta' => '123',
26 | 'conta_dac' => '1',
27 | ));
28 |
29 | // você pode adicionar vários boletos em uma remessa
30 | $arquivo->insertDetalhe(array(
31 | 'codigo_ocorrencia' => 1, // 1 = Entrada de título, futuramente poderemos ter uma constante
32 | 'nosso_numero' => '12345679',
33 | 'numero_documento' => '12345678',
34 | 'carteira' => '111',
35 | 'especie' => \Cnab\Especie::ITAU_DIVERSOS, // Você pode consultar as especies Cnab\Especie::CEF_OUTROS, futuramente poderemos ter uma tabela na documentação
36 | 'aceite' => 'Z', // "S" ou "N"
37 | 'valor' => 100.39, // Valor do boleto
38 | 'instrucao1' => '', // 1 = Protestar com (Prazo) dias, 2 = Devolver após (Prazo) dias, futuramente poderemos ter uma constante
39 | 'instrucao2' => '', // preenchido com zeros
40 | 'sacado_razao_social' => 'Nome do cliente', // O Sacado é o cliente, preste atenção nos campos abaixo
41 | 'sacado_tipo' => 'cnpj', //campo fixo, escreva 'cpf' (sim as letras cpf) se for pessoa fisica, cnpj se for pessoa juridica
42 | 'sacado_cnpj' => '21.222.333.4444-55',
43 | 'sacado_logradouro' => 'Logradouro do cliente',
44 | 'sacado_bairro' => 'Bairro do cliente',
45 | 'sacado_cep' => '00000-111',
46 | 'sacado_cidade' => 'Cidade do cliente',
47 | 'sacado_uf' => 'BA',
48 | 'data_vencimento' => new \DateTime('2015-02-03'),
49 | 'data_cadastro' => new \DateTime('2015-01-14'),
50 | 'juros_de_um_dia' => 0.10, // Valor do juros de 1 dia'
51 | 'data_desconto' => new \DateTime('2015-02-09'),
52 | 'valor_desconto' => 10.0, // Valor do desconto
53 | 'prazo' => 10, // prazo de dias para o cliente pagar após o vencimento
54 | 'taxa_de_permanencia' => '0', //00 = Acata Comissão por Dia (recomendável), 51 Acata Condições de Cadastramento na CAIXA
55 | 'mensagem' => 'Descrição do boleto',
56 | 'data_multa' => new \DateTime('2015-02-07'), // data da multa
57 | 'valor_multa' => 0.20, // valor da multa
58 | 'tipo_multa' => 'porcentagem',
59 | ));
60 |
61 | $texto = $arquivo->getText();
62 | $lines = explode("\r\n", trim($texto, "\r\n"));
63 |
64 | $this->assertEquals(3, count($lines));
65 | $headerText = $lines[0];
66 | $detalheText = $lines[1];
67 | //$compl1Text = $lines[2];
68 | $trailerText = $lines[2];
69 |
70 | $asserts = array(
71 | 'header' => array(
72 | '1:1' => '0',
73 | '2:2' => '1',
74 | '3:9' => 'REMESSA',
75 | '10:11' => '01',
76 | '12:26' => 'COBRANCA ',
77 | '27:30' => '1234',
78 | '31:32' => '00',
79 | '33:37' => '00123',
80 | '38:38' => '1',
81 | '39:46' => ' ',
82 | '47:76' => str_pad('Nome Fantasia da sua empresa', 30),
83 | '77:79' => '341',
84 | '80:94' => str_pad('BANCO ITAU SA', 15),
85 | '95:100' => '010215',
86 | '101:394' => str_pad(' ', 294),
87 | '395:400' => sprintf('%06d', 1),
88 | ),
89 | 'detalhe' => array(
90 | '1:1' => '1',
91 | '2:3' => '02', // empresa
92 | '4:17' => '11222333444455', // empresa
93 | '18:21' => '1234',
94 | '22:23' => '00',
95 | '24:28' => '00123',
96 | '29:29' => '1',
97 | '30:33' => ' ',
98 | '34:37' => '0000',
99 | '38:62' => str_pad('12345679', 25),
100 | '63:70' => '12345679',
101 | '71:83' => sprintf('%013d', 0),
102 | '84:86' => '0111',
103 | '87:107' => str_pad(' ', 21),
104 | '108:108' => 'I',
105 | '109:110' => '01',
106 | '111:120' => str_pad('12345678', 10),
107 | '121:126' => '030215',
108 | '127:139' => '0000000010039',
109 | '140:142' => '341',
110 | '143:147' => '00000',
111 | '148:149' => '99',
112 | '150:150' => 'Z',
113 | '151:156' => '140115',
114 | '157:158' => ' ',
115 | '159:160' => ' ',
116 | '161:173' => sprintf('%013d', 10),
117 | '174:179' => '090215',
118 | '180:192' => '0000000001000',
119 | '193:205' => sprintf('%013d', 0),
120 | '206:218' => sprintf('%013d', 0),
121 | '219:220' => '02', // 01 = CPF, 02 = CNPJ
122 | '221:234' => '21222333444455',
123 | '235:264' => str_pad('NOME DO CLIENTE', 30),
124 | '265:274' => str_pad(' ', 10),
125 | '275:314' => str_pad('LOGRADOURO DO CLIENTE', 40),
126 | '315:326' => 'BAIRRO DO CL',
127 | '327:334' => '00000111',
128 | '335:349' => str_pad('CIDADE DO CLIEN', 15),
129 | '350:351' => 'BA',
130 | '352:381' => str_pad('NOME FANTASIA DA SUA EMPRESA', 30),
131 | '382:385' => ' ',
132 | '386:391' => '070215',
133 | '392:393' => '10',
134 | '394:394' => ' ',
135 | '395:400' => sprintf('%06d', 2),
136 | ), /*
137 | 'compl1' => array(
138 | '1:1' => '2',
139 | '2:2' => '2',
140 | '3:10' => '07022015',
141 | '11:23' => '0000000000020',
142 | '24:394' => str_repeat(' ', 371),
143 | '395:400' => '000003'
144 | ),*/
145 | 'trailer' => array(
146 | '001:001' => '9',
147 | '002:394' => str_pad(' ', 393),
148 | '395:400' => sprintf('%06d', 3),
149 | ),
150 | );
151 |
152 | foreach ($asserts as $tipo => $campos) {
153 | $vname = "{$tipo}Text";
154 | foreach ($campos as $pos => $value) {
155 | $aux = explode(':', $pos);
156 | $start = $aux[0] - 1;
157 | $end = ($aux[1] - $aux[0]) + 1;
158 | $this->assertEquals($value, substr($$vname, $start, $end), "[ ] $tipo ($pos)");
159 | }
160 | }
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/tests/Cnab/Retorno/Cnab240/ArquivoTest.php:
--------------------------------------------------------------------------------
1 | createRetorno('tests/fixtures/cnab240/retorno_santander.ret');
11 | $this->assertNotNull($arquivo);
12 | $this->assertNotNull($arquivo->header);
13 | $this->assertNotNull($arquivo->lotes);
14 | $this->assertNotNull($arquivo->trailer);
15 |
16 | $this->assertEquals(11111111, $arquivo->getConta());
17 | $this->assertEquals(9, $arquivo->getContaDac());
18 | $this->assertEquals(33, $arquivo->getCodigoBanco());
19 |
20 | $detalhe = $arquivo->listDetalhes();
21 | $detalhe = $detalhe[0];
22 |
23 | $this->assertEquals(1040, $detalhe->segmento_t->nosso_numero);
24 | $this->assertEquals(10, $detalhe->segmento_t->valor_titulo);
25 | }
26 |
27 | public function testArquivoBancoDoBrasilPodeSerLido()
28 | {
29 | $factory = new \Cnab\Factory();
30 | $arquivo = $factory->createRetorno('tests/fixtures/cnab240/retorno_bb.ret');
31 | $this->assertNotNull($arquivo);
32 | $this->assertNotNull($arquivo->header);
33 | $this->assertNotNull($arquivo->lotes);
34 | $this->assertNotNull($arquivo->trailer);
35 |
36 | $this->assertEquals(7536, $arquivo->getConta());
37 | $this->assertEquals(7, $arquivo->getContaDac());
38 | $this->assertEquals(1, $arquivo->getCodigoBanco());
39 | $this->assertEquals(3294860, $arquivo->getCodigoConvenio());
40 |
41 | $this->assertEquals(
42 | \DateTime::createFromFormat('d/m/Y', '21/03/2011'),
43 | $arquivo->getDataGeracao()
44 | );
45 |
46 | $detalhe = $arquivo->listDetalhes();
47 | $detalhe = $detalhe[0];
48 |
49 | $this->assertEquals(40.00, $detalhe->getValorTitulo());
50 | $this->assertEquals(196, $detalhe->getNossoNumero());
51 | }
52 |
53 | public function testArquivoCaixaSigcbPodeSerLido()
54 | {
55 | $factory = new \Cnab\Factory();
56 | $arquivo = $factory->createRetorno('tests/fixtures/cnab240/retorno_cnab240_caixa.ret');
57 | $this->assertNotNull($arquivo);
58 | $this->assertNotNull($arquivo->header);
59 | $this->assertNotNull($arquivo->lotes);
60 | $this->assertNotNull($arquivo->trailer);
61 |
62 | $this->assertEquals(104, $arquivo->getCodigoBanco());
63 |
64 | $this->assertEquals(
65 | \DateTime::createFromFormat('d/m/Y', '06/01/2014'),
66 | $arquivo->getDataGeracao()
67 | );
68 |
69 | $detalhe = $arquivo->listDetalhes();
70 | $detalhe = $detalhe[0];
71 |
72 | $this->assertEquals(6, $detalhe->getCodigo());
73 | $this->assertEquals(80.00, $detalhe->getValorRecebido());
74 | $this->assertEquals(80.00, $detalhe->getValorTitulo());
75 | $this->assertEquals(1.25, $detalhe->getValorTarifa());
76 | $this->assertEquals(0, $detalhe->getValorIOF());
77 | $this->assertEquals(0, $detalhe->getValorDesconto());
78 | $this->assertEquals(0, $detalhe->getValorAbatimento());
79 | $this->assertEquals(0, $detalhe->getValorOutrosCreditos());
80 | $this->assertEquals(0, $detalhe->getValorMoraMulta());
81 | $this->assertEquals(null, $detalhe->getNumeroDocumento());
82 | $this->assertEquals(null, $detalhe->getCarteira());
83 | $this->assertEquals('0', $detalhe->getAgencia());
84 | $this->assertEquals(11136997, $detalhe->getNossoNumero());
85 | $this->assertEquals(new \DateTime('2014-01-02 00:00:00'), $detalhe->getDataVencimento());
86 | $this->assertEquals(new \DateTime('2014-01-07 00:00:00'), $detalhe->getDataCredito());
87 | $this->assertEquals(new \DateTime('2014-01-06 00:00:00'), $detalhe->getDataOcorrencia());
88 | $this->assertEquals(1086, $detalhe->getAgenciaCobradora());
89 | $this->assertEquals(0, $detalhe->getAgenciaCobradoraDac());
90 | $this->assertEquals(1, $detalhe->getNumeroSequencial());
91 | //$this->assertEquals('LIQUIDAÇÃO NORMAL', $detalhe->getCodigoNome());
92 | $this->assertEquals(true, $detalhe->isBaixa());
93 | $this->assertEquals(false, $detalhe->isBaixaRejeitada());
94 | $this->assertEquals(null, $detalhe->getCodigoLiquidacao());
95 | $this->assertEquals(false, $detalhe->isDDA());
96 | $this->assertEquals(null, $detalhe->getAlegacaoPagador());
97 | $this->assertEquals(null, $detalhe->getDescricaoLiquidacao());
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/tests/Cnab/Retorno/Cnab400/ArquivoTest.php:
--------------------------------------------------------------------------------
1 | createRetorno('tests/fixtures/cnab400/retorno-cb030400-bradesco.ret');
11 | $this->assertNotNull($arquivo);
12 | $this->assertNotNull($arquivo->header);
13 | $this->assertNotNull($arquivo->trailer);
14 |
15 | $this->assertEquals(4466911, $arquivo->getCodigoCedente());
16 | $this->assertEquals(\Cnab\Banco::BRADESCO, $arquivo->getCodigoBanco());
17 |
18 | $detalhes = $arquivo->listDetalhes();
19 | $detalhe = $detalhes[1];
20 |
21 | $this->assertEquals(new \DateTime('2012-04-12 00:00:00'), $detalhe->getDataVencimento());
22 | $this->assertEquals(5.0, $detalhe->getValorRecebido());
23 | $this->assertEquals(97, $detalhe->getNossoNumero());
24 | $this->assertEquals(15, $detalhe->getNumeroDocumento());
25 | $this->assertEquals(new \DateTime('2012-04-11 00:00:00'), $detalhe->getDataOcorrencia());
26 | }
27 |
28 | public function testArquivoBancoDoBrasilCnab400PodeSerLido()
29 | {
30 | $factory = new \Cnab\Factory();
31 | $arquivo = $factory->createRetorno('tests/fixtures/cnab400/retorno-cnab400-bb.ret');
32 |
33 | $this->assertNotNull($arquivo);
34 | $this->assertNotNull($arquivo->header);
35 | $this->assertNotNull($arquivo->trailer);
36 |
37 | $this->assertEquals('33448000011113', $arquivo->getCodigoCedente());
38 | $this->assertEquals(\Cnab\Banco::BANCO_DO_BRASIL, $arquivo->getCodigoBanco());
39 |
40 | $detalhes = $arquivo->listDetalhes();
41 | $detalhe = $detalhes[0];
42 |
43 | $this->assertEquals(25.0, $detalhe->getValorRecebido());
44 | $this->assertEquals('11122450000000290', $detalhe->getNossoNumero());
45 | $this->assertEquals(new \DateTime('2015-09-10 00:00:00'), $detalhe->getDataCredito());
46 | $this->assertEquals(new \DateTime('2015-09-08 00:00:00'), $detalhe->getDataOcorrencia());
47 | $this->assertTrue($detalhe->isBaixa());
48 | }
49 |
50 | public function testArquivoItauCnab400PodeSerLido()
51 | {
52 | $factory = new \Cnab\Factory();
53 | $arquivo = $factory->createRetorno('tests/fixtures/cnab400/retorno-cnab400-itau.ret');
54 | $this->assertNotNull($arquivo);
55 | $this->assertNotNull($arquivo->header);
56 | $this->assertNotNull($arquivo->trailer);
57 |
58 | $this->assertEquals(\Cnab\Banco::ITAU, $arquivo->getCodigoBanco());
59 |
60 | $detalhes = $arquivo->listDetalhes();
61 |
62 | $this->assertEquals(4, count($detalhes));
63 | $detalhe = $detalhes[0];
64 |
65 | $this->assertEquals(12345, $arquivo->getConta());
66 | $this->assertEquals(0, $arquivo->getContaDac());
67 | $this->assertEquals(341, $arquivo->getCodigoBanco());
68 | $this->assertEquals(new \DateTime('2013-08-22 00:00:00'), $arquivo->getDataGeracao());
69 | $this->assertEquals(new \DateTime('2013-06-21 00:00:00'), $arquivo->getDataCredito());
70 |
71 | $this->assertEquals(6, $detalhe->getCodigo());
72 | $this->assertEquals(209.97, $detalhe->getValorRecebido());
73 | $this->assertEquals(389.75, $detalhe->getValorTitulo());
74 | $this->assertEquals(3.33, $detalhe->getValorTarifa());
75 | $this->assertEquals(0.1, $detalhe->getValorIOF());
76 | $this->assertEquals(176.45, $detalhe->getValorDesconto());
77 | $this->assertEquals(0.19, $detalhe->getValorAbatimento());
78 | $this->assertEquals(0.18, $detalhe->getValorOutrosCreditos());
79 | $this->assertEquals(123123.12, $detalhe->getValorMoraMulta());
80 | $this->assertEquals('1A', $detalhe->getNumeroDocumento());
81 | $this->assertEquals(109, $detalhe->getCarteira());
82 | $this->assertEquals('0177', $detalhe->getAgencia());
83 | $this->assertEquals(231327, $detalhe->getNossoNumero());
84 | $this->assertEquals(null, $detalhe->getDataVencimento());
85 | $this->assertEquals(new \DateTime('2013-06-21 00:00:00'), $detalhe->getDataCredito());
86 | $this->assertEquals(new \DateTime('2013-06-20 00:00:00'), $detalhe->getDataOcorrencia());
87 | $this->assertEquals(3027, $detalhe->getAgenciaCobradora());
88 | $this->assertEquals(2, $detalhe->getAgenciaCobradoraDac());
89 | $this->assertEquals(2, $detalhe->getNumeroSequencial());
90 | $this->assertEquals('LIQUIDAÇÃO NORMAL', $detalhe->getCodigoNome());
91 | $this->assertEquals(false, $detalhe->isBaixa());
92 | $this->assertEquals(false, $detalhe->isBaixaRejeitada());
93 | $this->assertEquals('B2', $detalhe->getCodigoLiquidacao());
94 | $this->assertEquals(false, $detalhe->isDDA());
95 | $this->assertEquals(null, $detalhe->getAlegacaoPagador());
96 | $this->assertEquals('OUTROS BANCOS – PELA LINHA DIGITÁVEL', $detalhe->getDescricaoLiquidacao());
97 |
98 | $this->assertNotEmpty($detalhe->getDescricaoLiquidacao());
99 |
100 | // teste boleto dda e alegacao sacado
101 | $detalhe = $detalhes[1];
102 |
103 | $this->assertEquals(true, $detalhe->isDDA());
104 | $this->assertEquals('BOLETO DDA, DIVIDA NÃO RECONHECIDA PELO PAGADOR', $detalhe->getAlegacaoPagador());
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/tests/Cnab/Retorno/CodigoOcorrenciaTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('entrada confirmada', strtolower($codigoOcorrencia->getNome(237, 2, 'cnab400')));
13 | $this->assertEquals('entrada confirmada', strtolower($codigoOcorrencia->getNome(237, 2)));
14 | $this->assertEquals(null, strtolower($codigoOcorrencia->getNome(237, 25446)));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | getFields() as $field) {
7 | echo " '{$field->pos_start}:{$field->pos_end}' => '{$field->getEncoded()}', // {$field->nome} \n";
8 | }
9 | };
10 |
11 | echo "\n";
12 | echo "$assets = array(\n";
13 | echo " 'headerArquivo' => array(\n";
14 | $dumpLine($arquivo->headerArquivo);
15 | echo " ),\n";
16 | echo " 'headerLote' => array(\n";
17 | $dumpLine($arquivo->headerLote);
18 | echo " ),\n";
19 | echo " 'segmentoP' => array(\n";
20 | $dumpLine($arquivo->detalhes[0]->segmento_p);
21 | echo " ),\n";
22 | echo " 'segmentoQ' => array(\n";
23 | $dumpLine($arquivo->detalhes[0]->segmento_q);
24 | echo " ),\n";
25 | echo " 'segmentoR' => array(\n";
26 | $dumpLine($arquivo->detalhes[0]->segmento_r);
27 | echo " ),\n";
28 | echo " 'trailerLote' => array(\n";
29 | $dumpLine($arquivo->trailerLote);
30 | echo " ),\n";
31 | echo " 'trailerArquivo' => array(\n";
32 | $dumpLine($arquivo->trailerArquivo);
33 | echo " ),\n";
34 |
--------------------------------------------------------------------------------
/tests/fixtures/cnab240/retorno_bb.ret:
--------------------------------------------------------------------------------
1 | 00100000 2026599530001760032948600014 0032860000000075367 SAPATARIA E CONFECSOES JIBA BANCO DO BRASIL 22103201102475000025703000000909214318PROCESSAMEN
2 | 00100011T0100020 20026599530001760032948600014 0032860000000075367 SAPATARIA E CONFECSOES JIBA 000000002103201100000000 000000000
3 | 0010001300001T 060032860000000075367 32948600000000196 1 23032011000000000004000237009880 0900000000000000000000000000000000000000000000000000000 000000000000000000000050000 180273294860
4 | 0010001300002U 060000000000000000000000000000000000000000000000000000000000000000000000040000000000000035000000000000000000000000000000002103201123032011 000000000000000 000
5 | 0010001300003T 060032860000000075367 32948600000000236 1 25032011000000000003000033045680 0900000000000000000000000000000000000000000000000000000 000000000000000000000050000 180273294860
6 | 0010001300004U 060000000000000000000000000000000000000000000000000000000000000000000000030000000000000025000000000000000000000000000000002103201123032011 000000000000000 000
7 | 0010001300005T 060032860000000075367 32948600000000244 1 23032011000000000001500104004900 0900000000000000000000000000000000000000000000000000000 000000000000000000000050000 180273294860
8 | 0010001300006U 060000000000000000000000000000000000000000000000000000000000000000000000015000000000000010000000000000000000000000000000002103201123032011 000000000000000 000
9 | 0010001300007T 060032860000000075367 32948600000000249 1 23032011000000000001500104022660 0900000000000000000000000000000000000000000000000000000 000000000000000000000050000 180273294860
10 | 0010001300008U 060000000000000000000000000000000000000000000000000000000000000000000000015000000000000010000000000000000000000000000000002103201123032011 000000000000000 000
11 | 0010001300009T 060032860000000075367 32948600000005048 1 01042011000000000002880033002570 0900000000000000000000000000000000000000000000000000000 000000000000000000000050000 180273294860
12 | 0010001300010U 060000000000000000000000000000000000000000000000000000000000000000000000028800000000000023800000000000000000000000000000002103201123032011 000000000000000 000
13 | 00100015 000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
14 | 00199999 000001000014000000 00000000000000000000000000000
15 |
--------------------------------------------------------------------------------
/tests/fixtures/cnab240/retorno_cnab240_caixa.ret:
--------------------------------------------------------------------------------
1 | 10400000 2090183800001990000000000000000000001234204321000000000EMPRESA C ECON FEDERAL 20601201405551100162204000000 RETORNO-PRODUCAO 000
2 | 10400011T0100030 20090183800001990000000000000000000001234204321000000000EMPRESA 00001622060120140000000000 00
3 | 1040001300001T 060000000432100000000 240000000111369979100000000000000002012014000000000008000000010860000000000000000 090000000000000000 000000000000125020101
4 | 1040001300002U 06000000000000000000000000000000000000000000000000000000000000000000000008000000000000008000000000000000000000000000000000060120140701201400000701201400000000000000000000000000000000000000000000000000000000000000000000
5 | 1040001300003T 060000000432100000000 240000000111381979100000000000000005012014000000000008000000033170000000000000000 090000000000000000 000000000000125020101
6 | 1040001300004U 06000000000000000000000000000000000000000000000000000000000000000000000008000000000000008000000000000000000000000000000000060120140701201400000701201400000000000000000000000000000000000000000000000000000000000000000000
7 | 1040001300005T 060000000432100000000 240000000111378897100000000000000010012014000000000008000000011920000000000000000 090000000000000000 000000000000125020101
8 | 1040001300006U 06000000000000000000000000001000000000000000000000000000000000000000000007000000000000007000000000000000000000000000000000060120140701201400000701201400000000000000000000000000000000000000000000000000000000000000000000
9 | 1040001300007T 060000000432100000000 240000000111371256100000000000000010012014000000000008000000011920000000000000000 090000000000000000 000000000000125020101
10 | 1040001300008U 06000000000000000000000000001000000000000000000000000000000000000000000007000000000000007000000000000000000000000000000000060120140701201400000701201400000000000000000000000000000000000000000000000000000000000000000000
11 | 1040001300009T 060000000432100000000 240000000000222473100000000000000015012014000000000008000000002700000000000000000 090000000000000000 000000000000125020101
12 | 1040001300010U 06000000000000000000000000001000000000000000000000000000000000000000000007000000000000007000000000000000000000000000000000060120140701201400000701201400000000000000000000000000000000000000000000000000000000000000000000
13 | 1040001300011T 060000000432100000000 240000000111369162100000000000000010012014000000000008000000031280000000000000000 090000000000000000 000000000000125020101
14 | 1040001300012U 06000000000000000000000000001000000000000000000000000000000000000000000007000000000000007000000000000000000000000000000000060120140701201400000701201400000000000000000000000000000000000000000000000000000000000000000000
15 | 1040001300013T 060000000432100000000 240000000111368980100000000000000010012014000000000008000000036620000000000000000 090000000000000000 000000000000125020101
16 | 1040001300014U 06000000000000000000000000000000000000000000000000000000000000000000000008000000000000008000000000000000000000000000000000060120140701201400000701201400000000000000000000000000000000000000000000000000000000000000000000
17 | 1040001300015T 060000000432100000000 240000000000319990100000000000000010012014000000000048000000011920000000000000000 090000000000000000 000000000000125020101
18 | 1040001300016U 06000000000000000000000000006000000000000000000000000000000000000000000042000000000000042000000000000000000000000000000000060120140701201400000701201400000000000000000000000000000000000000000000000000000000000000000000
19 | 1040001300017T 060000000432100000000 240000000000305727100000000000000010012014000000000008000237017950000000000000000 090000000000000000 000000000000270040101
20 | 1040001300018U 06000000000000000000000000001000000000000000000000000000000000000000000007000000000000007000000000000000000000000000000000060120140701201400000701201400000000000000000000000000000000000000000000000000000000000000000000
21 | 10400015 00002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
22 | 10499999 000001000022
23 |
--------------------------------------------------------------------------------
/tests/fixtures/cnab240/retorno_santander.ret:
--------------------------------------------------------------------------------
1 | 03300000 2011111111111111456750111111119 001111111 EMPRESA DE TESTE E NOME GRANDEBANCO SANTANDER (BRASIL) S/A 204062014 000077040
2 | 03370311T01 040 2011111111111111001111111 456750111111119 EMPRESA DE TESTE E NOME GRANDE 0000007704062014
3 | 0337031300001T 17456750111111119 00000000010401 0406201400000000000100003303530 002000000000000000 01111111190000000000003240300000000
4 | 0337031300002U 170000000000000000000000000000000000000000000000000000000000000000000000011000000000000011000000000000000000000000000001000406201405062014000000000000000000000000000 000
5 | 03370315 0000020000010000000000005489000000000000000000000000000000000000000000000000000000000000000000000000000076
6 | 03370319 000001000006
7 |
--------------------------------------------------------------------------------
/tests/fixtures/cnab400/retorno-cb030400-bradesco.ret:
--------------------------------------------------------------------------------
1 | 02RETORNO01COBRANCA 00000000000004466911COOPERATIVA DE SERVICOS TECNIC237BRADESCO 1104120160000000042 130412 000001
2 | 1020414679200016800000090142000169102 00000000000000000097000000000000000000000000090211041215 00000000000000000097120412000000000050023700523 000000000025200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000 000002
3 | 1020414679200016800000090142000169102 00000000000000000097000000000000000000000000090611041215 00000000000000000097120412000000000050023701420 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000 130412 00000000000000 000003
4 | 1020414679200016800000090142000169102 000000000000000001860000000000000000000000000917110412 00000000000000000186000000000000000000200101886 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000 130412 0000000000 000004
5 | 1020414679200016800000090142000169102 000000000000000001940000000000000000000000000917110412 00000000000000000194000000000000000000200101886 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000 130412 0000000000 000005
6 | 1020414679200016800000090142000169102 000000000000000002080000000000000000000000000917110412 00000000000000000208000000000000000000200101886 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000 130412 0000000000 000006
7 | 1020414679200016800000090142000169102 000000000000000002160000000000000000000000000917110412 00000000000000000216000000000000000000200101886 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000 130412 0000000000 000007
8 | 1020414679200016800000090142000169102 000000000000000002240000000000000000000000000917110412 00000000000000000224000000000000000000200101886 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000 130412 0000000000 000008
9 | 9201237 000000010000000000020000000042 00001000000000500000000000500000010000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000 000009
10 |
--------------------------------------------------------------------------------
/tests/fixtures/cnab400/retorno-cnab400-bb.ret:
--------------------------------------------------------------------------------
1 | 02RETORNO01COBRANCA 33448000011113000000EMPRESA TESTE 001BANCO DO BRASIL0809150000017 000000017910400476 1112245 000001
2 | 70000000000000000334480000112131112245 1112245000000029010000001 01900000000000 1806080915 000000000000000250000157045001009150000900000000000000000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000160020000000000000 0000000000000000000000000000000000000000000000001002000002
3 | 9201001 000000000000000000000000000000 000000000000000000000000000000 000000000000000000000000000000 000000000000000000000000000000 000000000000000000000000000000 000003
4 |
--------------------------------------------------------------------------------
/tests/fixtures/cnab400/retorno-cnab400-itau.ret:
--------------------------------------------------------------------------------
1 | 02RETORNO01COBRANCA 011100123450 Teste de Retorno 341BANCO ITAU S.A.22081301600BPI00112210613 000001
2 | 10209361352000321017700653730 00231327 109002313270 I06200613 1A00231327 000000000000003897500130272 000000000033300000000000000000000000000000000000001000000000000190000000017645000000002099700000123123120000000000018 21061300000000000000000000000 B2000002
3 | 10209361352000321017700653730 00123442 109001234425 I25200613 00123442 000000000000005650000130272 0000000000333000000000000000000000000000000000000000000000000000000000000197150000000036452000000000000000000000000001 21061300000000000000000000000 1842 B2000003
4 | 10209361352000321017700653730 00211842 109002118429 I06200613 00211842 000000000000003954134103673 000000000033300000000000000000000000000000000000000000000000000000000000000000000000003920900000000000010000000000000 21061300000000000000000000000 BL000004
5 | 10209361352000321017700653730 00237636 109002376365 I06200613 00237636 000000000000005456023728753 000000000033300000000000000000000000000000000000000000000000000000000000020160000000003406700000000000000000000000000 21061300000000000000000000000 B1000005
6 | 9201341 000000000000000000000000000000 000000000000000000000000000000 000000000000000000000000000000 000000000000000000000000000000001120000000400000000189576 000006
7 |
--------------------------------------------------------------------------------