Test Failed
Push — master ( e53a66...43458c )
by Francimar
16:26
created

Recibo   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 271
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 46.31%

Importance

Changes 0
Metric Value
wmc 45
lcom 1
cbo 5
dl 0
loc 271
ccs 69
cts 149
cp 0.4631
rs 8.3673
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getNumero() 0 7 2
A setNumero() 0 5 1
A setTempoMedio() 0 5 1
A setCodigo() 0 5 1
A setMensagem() 0 5 1
C fromArray() 0 35 8
A getTempoMedio() 0 7 2
A getCodigo() 0 7 2
A getMensagem() 0 7 2
A getModelo() 0 13 4
A setModelo() 0 13 3
A toArray() 0 10 1
A envia() 0 19 2
A consulta() 0 13 4
A getNode() 0 14 2
B loadNode() 0 24 4
B validar() 0 23 4

How to fix   Complexity   

Complex Class

Complex classes like Recibo often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Recibo, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * MIT License
4
 *
5
 * Copyright (c) 2016 MZ Desenvolvimento de Sistemas LTDA
6
 *
7
 * @author Francimar Alves <[email protected]>
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in all
17
 * copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
 * SOFTWARE.
26
 *
27
 */
28
namespace NFe\Task;
29
30
use NFe\Core\Nota;
31
use NFe\Common\Util;
32
use NFe\Exception\ValidationException;
33
34
class Recibo extends Retorno
35
{
36
37
    const INFO_TAGNAME = 'infRec';
38
39
    private $numero;
40
    private $tempo_medio;
41
    private $codigo;
42
    private $mensagem;
43
    private $modelo;
44
45 6
    public function __construct($recibo = [])
46
    {
47 6
        parent::__construct($recibo);
48 6
    }
49
50
    /**
51
     * Número do Recibo
52
     */
53
    public function getNumero($normalize = false)
54
    {
55
        if (!$normalize) {
56
            return $this->numero;
57
        }
58
        return $this->numero;
59
    }
60
61 6
    public function setNumero($numero)
62
    {
63 6
        $this->numero = $numero;
64 6
        return $this;
65
    }
66
67
    /**
68
     * Tempo médio de resposta do serviço (em segundos) dos últimos 5 minutos
69
     */
70 1
    public function getTempoMedio($normalize = false)
71
    {
72 1
        if (!$normalize) {
73
            return $this->tempo_medio;
74
        }
75 1
        return $this->tempo_medio;
76
    }
77
78 6
    public function setTempoMedio($tempo_medio)
79
    {
80 6
        $this->tempo_medio = $tempo_medio;
81 6
        return $this;
82
    }
83
84
    /**
85
     * Código da Mensagem (v2.0) alterado para tamanho variavel 1-4.
86
     * (NT2011/004)
87
     */
88 1
    public function getCodigo($normalize = false)
89
    {
90 1
        if (!$normalize) {
91
            return $this->codigo;
92
        }
93 1
        return $this->codigo;
94
    }
95
96 6
    public function setCodigo($codigo)
97
    {
98 6
        $this->codigo = $codigo;
99 6
        return $this;
100
    }
101
102
    /**
103
     * Mensagem da SEFAZ para o emissor. (v2.0)
104
     */
105 1
    public function getMensagem($normalize = false)
106
    {
107 1
        if (!$normalize) {
108
            return $this->mensagem;
109
        }
110 1
        return $this->mensagem;
111
    }
112
113 6
    public function setMensagem($mensagem)
114
    {
115 6
        $this->mensagem = $mensagem;
116 6
        return $this;
117
    }
118
119
    /**
120
     * Código do modelo do Documento Fiscal. 55 = NF-e; 65 = NFC-e.
121
     * @param boolean $normalize informa se o modelo deve estar no formato do XML
122
     * @return mixed modelo do Envio
123
     */
124 1
    public function getModelo($normalize = false)
125
    {
126 1
        if (!$normalize) {
127 1
            return $this->modelo;
128
        }
129 1
        switch ($this->modelo) {
130 1
            case Nota::MODELO_NFE:
131 1
                return '55';
132 1
            case Nota::MODELO_NFCE:
133 1
                return '65';
134
        }
135 1
        return $this->modelo;
136
    }
137
138
    /**
139
     * Altera o valor do Modelo para o informado no parâmetro
140
     * @param mixed $modelo novo valor para Modelo
141
     * @return Envio A própria instância da classe
142
     */
143 6
    public function setModelo($modelo)
144
    {
145
        switch ($modelo) {
146 6
            case '55':
147 1
                $modelo = Nota::MODELO_NFE;
148 1
                break;
149 6
            case '65':
150 1
                $modelo = Nota::MODELO_NFCE;
151 1
                break;
152
        }
153 6
        $this->modelo = $modelo;
154 6
        return $this;
155
    }
156
157
    public function toArray($recursive = false)
158
    {
159
        $recibo = parent::toArray($recursive);
160
        $recibo['numero'] = $this->getNumero();
161
        $recibo['tempo_medio'] = $this->getTempoMedio();
162
        $recibo['codigo'] = $this->getCodigo();
163
        $recibo['mensagem'] = $this->getMensagem();
164
        $recibo['modelo'] = $this->getModelo();
165
        return $recibo;
166
    }
167
168 6
    public function fromArray($recibo = [])
169
    {
170 6
        if ($recibo instanceof Recibo) {
171
            $recibo = $recibo->toArray();
172 6
        } elseif (!is_array($recibo)) {
173
            return $this;
174
        }
175 6
        parent::fromArray($recibo);
176 6
        if (isset($recibo['numero'])) {
177
            $this->setNumero($recibo['numero']);
178
        } else {
179 6
            $this->setNumero(null);
180
        }
181 6
        if (isset($recibo['tempo_medio'])) {
182
            $this->setTempoMedio($recibo['tempo_medio']);
183
        } else {
184 6
            $this->setTempoMedio(null);
185
        }
186 6
        if (isset($recibo['codigo'])) {
187
            $this->setCodigo($recibo['codigo']);
188
        } else {
189 6
            $this->setCodigo(null);
190
        }
191 6
        if (isset($recibo['mensagem'])) {
192
            $this->setMensagem($recibo['mensagem']);
193
        } else {
194 6
            $this->setMensagem(null);
195
        }
196 6
        if (isset($recibo['modelo'])) {
197
            $this->setModelo($recibo['modelo']);
198
        } else {
199 6
            $this->setModelo(null);
200
        }
201 6
        return $this;
202
    }
203
204
    public function envia($dom)
205
    {
206
        $envio = new Envio();
207
        $envio->setServico(Envio::SERVICO_RETORNO);
208
        $envio->setAmbiente($this->getAmbiente());
209
        $envio->setModelo($this->getModelo());
210
        $envio->setEmissao(Nota::EMISSAO_NORMAL);
211
        $this->setVersao($envio->getVersao());
212
        $dom = $this->validar($dom);
213
        $envio->setConteudo($dom);
214
        $resp = $envio->envia();
215
        $this->loadNode($resp);
216
        if (!$this->isProcessado()) {
217
            return $this;
218
        }
219
        $protocolo = new Protocolo();
220
        $protocolo->loadNode($resp);
221
        return $protocolo;
222
    }
223
224
    public function consulta($nota = null)
225
    {
226
        if (!is_null($nota)) {
227
            $this->setAmbiente($nota->getAmbiente());
228
            $this->setModelo($nota->getModelo());
229
        }
230
        $dom = $this->getNode()->ownerDocument;
231
        $retorno = $this->envia($dom);
232
        if ($retorno->isAutorizado() && !is_null($nota)) {
233
            $nota->setProtocolo($retorno);
234
        }
235
        return $retorno;
236
    }
237
238
    public function getNode($name = null)
239
    {
240
        $dom = new \DOMDocument('1.0', 'UTF-8');
241
        $element = $dom->createElement(is_null($name)?'consReciNFe':$name);
242
        $element->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', Nota::PORTAL);
243
        $versao = $dom->createAttribute('versao');
244
        $versao->value = Nota::VERSAO;
245
        $element->appendChild($versao);
246
247
        Util::appendNode($element, 'tpAmb', $this->getAmbiente(true));
248
        Util::appendNode($element, 'nRec', $this->getNumero(true));
249
        $dom->appendChild($element);
250
        return $element;
251
    }
252
253 1
    public function loadNode($element, $name = null)
254
    {
255 1
        $name = is_null($name)?'retConsReciNFe':$name;
256 1
        if ($name == self::INFO_TAGNAME) {
257 1
            $_fields = $element->getElementsByTagName($name);
258 1
            if ($_fields->length == 0) {
259 1
                throw new \Exception('Tag "'.$name.'" não encontrada', 404);
260
            }
261
            $element = $_fields->item(0);
262
        } else {
263
            $element = parent::loadNode($element, $name);
264
        }
265
        $this->setNumero(
266
            Util::loadNode(
267
                $element,
268
                'nRec',
269
                'Tag "nRec" do campo "Numero" não encontrada'
270
            )
271
        );
272
        $this->setTempoMedio(Util::loadNode($element, 'tMed'));
273
        $this->setCodigo(Util::loadNode($element, 'cMsg'));
274
        $this->setMensagem(Util::loadNode($element, 'xMsg'));
275
        return $element;
276
    }
277
278
    /**
279
     * Valida o documento após assinar
280
     */
281 1
    public function validar($dom)
282
    {
283 1
        $dom->loadXML($dom->saveXML());
284 1
        $xsd_path = dirname(__DIR__) . '/Core/schema';
285 1
        $xsd_file = $xsd_path . '/consReciNFe_v'.$this->getVersao().'.xsd';
286 1
        if (!file_exists($xsd_file)) {
287 1
            throw new \Exception(sprintf('O arquivo "%s" de esquema XSD não existe!', $xsd_file), 404);
288
        }
289
        // Enable user error handling
290
        $save = libxml_use_internal_errors(true);
291
        if ($dom->schemaValidate($xsd_file)) {
292
            libxml_use_internal_errors($save);
293
            return $dom;
294
        }
295
        $msg = [];
296
        $errors = libxml_get_errors();
297
        foreach ($errors as $error) {
298
            $msg[] = 'Não foi possível validar o XML: '.$error->message;
299
        }
300
        libxml_clear_errors();
301
        libxml_use_internal_errors($save);
302
        throw new ValidationException($msg);
303
    }
304
}
305