CNAB150Processor::processarDetalhe()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 31
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 2
Metric Value
c 7
b 0
f 2
dl 0
loc 31
rs 8.8571
cc 1
eloc 24
nc 1
nop 1
1
<?php
2
3
namespace Umbrella\Ya\RetornoBoleto\Cnab\Cnab150\Processor;
4
5
use Stringy\Stringy;
6
use Umbrella\Ya\RetornoBoleto\AbstractProcessor;
7
use Umbrella\Ya\RetornoBoleto\Cnab\Cnab150\Detail;
8
use Umbrella\Ya\RetornoBoleto\Cnab\Cnab150\Header;
9
use Umbrella\Ya\RetornoBoleto\Cnab\Cnab150\Trailer;
10
use Umbrella\Ya\RetornoBoleto\Cnab\ComposableInterface;
11
use Umbrella\Ya\RetornoBoleto\LoteInterface;
12
use Umbrella\Ya\RetornoBoleto\RetornoInterface;
13
use Umbrella\Ya\RetornoBoleto\Model\Banco;
14
use Umbrella\Ya\RetornoBoleto\Model\Cedente;
15
use Umbrella\Ya\RetornoBoleto\Model\Empresa;
16
17
/**
18
 * Classe para leitura_arquivos_retorno_cobranças_padrão CNAB150.<br/>
19
 * Layout Padrão Febraban 150 posições<br/>
20
 * @author Ítalo Lelis de Vietro <[email protected]>
21
 */
22
class CNAB150Processor extends AbstractProcessor
23
{
24
    /**
25
     * @property int HEADER_ARQUIVO Define o valor que identifica uma coluna do tipo HEADER DE ARQUIVO
26
     */
27
    const HEADER_ARQUIVO = 'A';
28
29
    /**
30
     * @property int DETALHE Define o valor que identifica uma coluna do tipo DETALHE
31
     */
32
    const DETALHE = 'G';
33
34
    /**
35
     * @property int TRAILER_ARQUIVO Define o valor que identifica uma coluna do tipo TRAILER DE ARQUIVO
36
     */
37
    const TRAILER_ARQUIVO = 'Z';
38
39
    public function createHeader()
40
    {
41
        return new Header();
42
    }
43
44
    protected function processarHeaderArquivo($linha)
45
    {
46
        $header = $this->createHeader();
47
48
        $header
49
            ->setRegistro($linha->substr(1, 1)->trim())
50
            ->setRemessa($linha->substr(2, 1)->trim())
51
            ->setConvenio($linha->substr(3, 20)->trim());
52
53
        $empresa = new Empresa();
54
        $empresa
55
            ->setNome($linha->substr(23, 20)->trim());
56
57
        $banco = new Banco();
58
        $banco
59
            ->setCod($linha->substr(43, 3)->trim())
60
            ->setNome($linha->substr(46, 20)->trim());
61
62
        $header
63
            ->setDataGeracao($this->createDateTime($linha->substr(66, 8)->trim(), "Ymd"))
64
            ->setSequencialRet($linha->substr(74, 6)->trim())
65
            ->setVersaoLayout($linha->substr(80, 2)->trim())
66
            ->setCodBarras($linha->substr(82, 17)->trim())
67
            ->setFiller($linha->substr(99, 52)->trim());
68
69
        $cedente = new Cedente();
70
        $cedente->setBanco($banco);
71
72
        $header
73
            ->setCedente($cedente)
74
            ->setEmpresa($empresa);
75
76
        return $header;
77
    }
78
79
    protected function processarDetalhe($linha)
80
    {
81
        $detail = new Detail();
82
83
        $detail
84
            ->setRegistro($linha->substr(1, 1)->trim())
85
            ->setDataPagamento($this->createDateTime($linha->substr(22, 8)->trim(), "Ymd"))
86
            ->setDataCredito($this->createDateTime($linha->substr(30, 8)->trim(), "Ymd"))
87
            ->setCodBarras($linha->substr(38, 44)->trim())
88
            ->setValorRecebido($linha->substr(82, 12)->trim())
89
            ->setValorTarifa($linha->substr(94, 7)->trim())
90
            ->setNumeroSequencial($linha->substr(101, 8)->trim())
91
            ->setCodigoAgenciaArrecadadora($linha->substr(109, 8)->trim())
92
            ->setFormaArrecadacao($linha->substr(117, 1)->trim())
93
            ->setNumeroAutenticacao($linha->substr(118, 23)->trim())
94
            ->setFormaPagamento($linha->substr(141, 1)->trim())
95
            ->setFiller($linha->substr(142, 9)->trim());
96
97
        $banco = new Banco();
98
        $banco
99
            ->setAgencia($linha->substr(2, 4)->trim())
100
            ->setConta($linha->substr(6, 14)->trim())
101
            ->setDvConta($linha->substr(20, 1)->trim());
102
103
        $cedente = new Cedente();
104
        $cedente->setBanco($banco);
105
106
        $detail->setCedente($cedente);
107
108
        return $detail;
109
    }
110
111
    protected function processarTrailerArquivo($linha)
112
    {
113
        $trailer = new Trailer();
114
115
        $trailer
116
            ->setRegistro($linha->substr(1, 1)->trim())
117
            ->setQuantidadeRegistros($linha->substr(2, 6)->trim())
118
            ->setValorTotal($linha->substr(8, 17)->trim())
119
            ->setFiller($linha->substr(25, 126)->trim());
120
121
        return $trailer;
122
    }
123
124
    /**
125
     * Processa uma linha_arquivo_retorno.
126
     * @param int $numLn Número_linha a ser processada
127
     * @param string $linha String contendo a linha a ser processada
128
     * @return array Retorna um vetor associativo contendo os valores_linha processada.
129
     */
130
    public function processarLinha($numLn, Stringy $linha)
131
    {
132
        //é adicionado um espaço vazio no início_linha para que
133
        //possamos trabalhar com índices iniciando_1, no lugar_zero,
134
        //e assim, ter os valores_posição_campos exatamente
135
        //como no manual CNAB150
136
        $linha = $linha->insert(" ", 0);
137
        $tipoLn = $linha->substr(1, 1)->trim();
138
139
        $this->needToCreateLote = false;
140
        if ((string)$tipoLn == self::HEADER_ARQUIVO) {
141
            $this->needToCreateLote = true;
142
            $vlinha = $this->processarHeaderArquivo($linha);
143
        } else if ((string)$tipoLn == self::DETALHE) {
144
            $vlinha = $this->processarDetalhe($linha);
145
        } else if ((string)$tipoLn == self::TRAILER_ARQUIVO) {
146
            $vlinha = $this->processarTrailerArquivo($linha);
147
        }
148
149
        return $vlinha;
0 ignored issues
show
Bug introduced by
The variable $vlinha does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
150
    }
151
152
    public function processCnab(RetornoInterface $retorno, ComposableInterface $composable, LoteInterface $lote = null)
153
    {
154
        switch ($composable->getRegistro()) {
155
            case self::HEADER_ARQUIVO:
156
                $retorno->setHeader($composable);
0 ignored issues
show
Compatibility introduced by
$composable of type object<Umbrella\Ya\Retor...ab\ComposableInterface> is not a sub-type of object<Umbrella\Ya\Retor...ab\CnabHeaderInterface>. It seems like you assume a child interface of the interface Umbrella\Ya\RetornoBoleto\Cnab\ComposableInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
157
                break;
158
159
            case self::TRAILER_ARQUIVO:
160
                $retorno->setTrailer($composable);
0 ignored issues
show
Compatibility introduced by
$composable of type object<Umbrella\Ya\Retor...ab\ComposableInterface> is not a sub-type of object<Umbrella\Ya\Retor...b\CnabTrailerInterface>. It seems like you assume a child interface of the interface Umbrella\Ya\RetornoBoleto\Cnab\ComposableInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
161
                break;
162
163
            case self::DETALHE:
164
                $lote->addDetail($composable);
0 ignored issues
show
Compatibility introduced by
$composable of type object<Umbrella\Ya\Retor...ab\ComposableInterface> is not a sub-type of object<Umbrella\Ya\Retor...ab\CnabDetailInterface>. It seems like you assume a child interface of the interface Umbrella\Ya\RetornoBoleto\Cnab\ComposableInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
Bug introduced by
It seems like $lote is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
165
                break;
166
        }
167
    }
168
}
169