Test Failed
Push — master ( 0b1763...830d7c )
by Francimar
19:46
created

Tarefa::toArray()   B

Complexity

Conditions 9
Paths 16

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 9

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 17
cts 17
cp 1
rs 8.0555
c 0
b 0
f 0
cc 9
nc 16
nop 1
crap 9
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
class Tarefa
31
{
32
33
    /**
34
     * Ação a ser realizada sobre o objeto ou recibo
35
     */
36
    const ACAO_CONSULTAR = 'consultar';
37
    const ACAO_INUTILIZAR = 'inutilizar';
38
    const ACAO_CANCELAR = 'cancelar';
39
40
    private $id;
41
    private $acao;
42
    private $nota;
43
    private $documento;
44
    private $agente;
45
    private $resposta;
46
47 17
    public function __construct($tarefa = [])
48
    {
49 17
        $this->fromArray($tarefa);
50 17
    }
51
52
    /**
53
     * Código aleatório e opcional que identifica a tarefa
54
     */
55 16
    public function getID()
56
    {
57 16
        return $this->id;
58
    }
59
60 17
    public function setID($id)
61
    {
62 17
        $this->id = $id;
63 17
        return $this;
64
    }
65
66
    /**
67
     * Ação a ser realizada sobre o objeto ou recibo
68
     */
69 16
    public function getAcao()
70
    {
71 16
        return $this->acao;
72
    }
73
74 17
    public function setAcao($acao)
75
    {
76 17
        $this->acao = $acao;
77 17
        return $this;
78
    }
79
80
    /**
81
     * Nota que será processada se informado
82
     */
83 16
    public function getNota()
84
    {
85 16
        return $this->nota;
86
    }
87
88 17
    public function setNota($nota)
89
    {
90 17
        $this->nota = $nota;
91 17
        return $this;
92
    }
93
94
    /**
95
     * Informa o XML do objeto, quando não informado o XML é gerado a partir do
96
     * objeto
97
     */
98 7
    public function getDocumento()
99
    {
100 7
        return $this->documento;
101
    }
102
103 17
    public function setDocumento($documento)
104
    {
105 17
        $this->documento = $documento;
106 17
        return $this;
107
    }
108
109
    /**
110
     * Agente que obteve ou vai obter a resposta, podendo ser: pedido de
111
     * inutilização(NF\Inutilizacao), recibo(NF\Recibo) ou pedido de
112
     * cancelamento(NF\Evento)
113
     */
114 16
    public function getAgente()
115
    {
116 16
        return $this->agente;
117
    }
118
119 17
    public function setAgente($agente)
120
    {
121 17
        $this->agente = $agente;
122 17
        return $this;
123
    }
124
125
    /**
126
     * Resposta da tarefa após ser executada
127
     */
128 7
    public function getResposta()
129
    {
130 7
        return $this->resposta;
131
    }
132
133 17
    public function setResposta($resposta)
134
    {
135 17
        $this->resposta = $resposta;
136 17
        return $this;
137
    }
138
139 3
    public function toArray($recursive = false)
140
    {
141 3
        $tarefa = [];
142 3
        $tarefa['id'] = $this->getID();
143 3
        $tarefa['acao'] = $this->getAcao();
144 3
        if (!is_null($this->getNota()) && $recursive) {
145 1
            $tarefa['nota'] = $this->getNota()->toArray($recursive);
146
        } else {
147 2
            $tarefa['nota'] = $this->getNota();
148
        }
149 3
        if (!is_null($this->getDocumento()) && $recursive) {
150 1
            $tarefa['documento'] = $this->getDocumento()->saveXML();
151
        } else {
152 3
            $tarefa['documento'] = $this->getDocumento();
153
        }
154 3
        if (!is_null($this->getAgente()) && $recursive) {
155 1
            $tarefa['agente'] = $this->getAgente()->toArray($recursive);
156
        } else {
157 2
            $tarefa['agente'] = $this->getAgente();
158
        }
159 3
        if (!is_null($this->getResposta()) && $recursive) {
160 1
            $tarefa['resposta'] = $this->getResposta()->toArray($recursive);
161
        } else {
162 2
            $tarefa['resposta'] = $this->getResposta();
163
        }
164 3
        return $tarefa;
165
    }
166
167 17
    public function fromArray($tarefa = [])
168
    {
169 17
        if ($tarefa instanceof Tarefa) {
170 1
            $tarefa = $tarefa->toArray();
171 17
        } elseif (!is_array($tarefa)) {
172 1
            return $this;
173
        }
174 17
        if (isset($tarefa['id'])) {
175 1
            $this->setID($tarefa['id']);
176
        } else {
177 17
            $this->setID(null);
178
        }
179 17
        if (isset($tarefa['acao'])) {
180 1
            $this->setAcao($tarefa['acao']);
181
        } else {
182 17
            $this->setAcao(null);
183
        }
184 17
        if (isset($tarefa['nota'])) {
185 1
            $this->setNota($tarefa['nota']);
186
        } else {
187 17
            $this->setNota(null);
188
        }
189 17
        if (isset($tarefa['documento'])) {
190 1
            $this->setDocumento($tarefa['documento']);
191
        } else {
192 17
            $this->setDocumento(null);
193
        }
194 17
        if (isset($tarefa['agente'])) {
195 1
            $this->setAgente($tarefa['agente']);
196
        } else {
197 17
            $this->setAgente(null);
198
        }
199 17
        if (isset($tarefa['resposta'])) {
200 1
            $this->setResposta($tarefa['resposta']);
201
        } else {
202 17
            $this->setResposta(null);
203
        }
204 17
        return $this;
205
    }
206
207
    /**
208
     * Resposta da tarefa após ser executada
209
     */
210 15
    public function executa()
211
    {
212 15
        if (is_null($this->getID())) {
213 15
            $this->setID(Status::genLote());
214
        }
215 15
        $retorno = null;
216 15
        switch ($this->getAcao()) {
217 15
            case self::ACAO_CANCELAR:
218 4
                $retorno = $this->cancela();
219 1
                break;
220 11
            case self::ACAO_INUTILIZAR:
221 6
                $retorno = $this->inutiliza();
222 2
                break;
223 5
            case self::ACAO_CONSULTAR:
224 5
                $retorno = $this->consulta();
225 3
                break;
226
        }
227 6
        $this->setResposta($retorno);
228 6
        return $this->getResposta();
229
    }
230
231 4
    private function cancela()
232
    {
233 4
        $nota = $this->getNota();
234 4
        $evento = $this->getAgente();
235 4
        if (is_null($evento)) {
236 3
            if (is_null($nota)) {
237 1
                throw new \Exception('A nota não foi informada na tarefa de cancelamento "'.$this->getID().'"', 404);
238
            }
239 2
            if (is_null($nota->getProtocolo())) {
240 1
                throw new \Exception('A nota não possui protocolo de autorização para o cancelamento "'.
241 1
                    $this->getID().'"', 404);
242
            }
243 1
            $evento = new Evento();
244 1
            $evento->setData(time());
245 1
            $evento->setOrgao($nota->getEmitente()->getEndereco()->
246 1
                getMunicipio()->getEstado()->getUF());
247 1
            $evento->setJustificativa($nota->getJustificativa());
248 1
            $this->setAgente($evento);
249 1
        } elseif (!($evento instanceof Evento)) {
250 1
            throw new \Exception('O agente informado não é um evento', 500);
251
        }
252 1
        if (!is_null($nota)) {
253 1
            $evento->setAmbiente($nota->getAmbiente());
254 1
            $evento->setModelo($nota->getModelo());
255 1
            $evento->setIdentificador($nota->getEmitente()->getCNPJ());
256 1
            if (!is_null($nota->getProtocolo())) {
257 1
                $evento->setNumero($nota->getProtocolo()->getNumero());
258
            }
259 1
            $evento->setChave($nota->getID());
260
        }
261 1
        $dom = $evento->getNode()->ownerDocument;
262 1
        $dom = $evento->assinar($dom);
263 1
        $retorno = $evento->envia($dom);
264 1
        if ($retorno->isCancelado()) {
265 1
            $dom = $evento->addInformacao($dom);
266 1
            $this->setDocumento($dom);
267
        }
268 1
        return $retorno;
269
    }
270
    
271 6
    private function inutiliza()
272
    {
273 6
        $nota = $this->getNota();
274 6
        $inutilizacao = $this->getAgente();
275 6
        if (is_null($inutilizacao)) {
276 2
            if (is_null($nota)) {
277 1
                throw new \Exception('A nota não foi informada na tarefa de inutilização "'.$this->getID().'"', 404);
278
            }
279 1
            $inutilizacao = new Inutilizacao();
280 1
            $inutilizacao->setAno(date('Y'));
281 1
            $inutilizacao->setJustificativa($nota->getJustificativa());
282 1
            $this->setAgente($inutilizacao);
283 4
        } elseif (!($inutilizacao instanceof Inutilizacao)) {
284 1
            throw new \Exception('O agente informado não é uma inutilização', 500);
285
        }
286 4
        if (!is_null($nota)) {
287 2
            $inutilizacao->setCNPJ($nota->getEmitente()->getCNPJ());
288 2
            $inutilizacao->setSerie($nota->getSerie());
289 2
            $inutilizacao->setInicio($nota->getNumero());
290 2
            $inutilizacao->setFinal($nota->getNumero());
291 2
            $inutilizacao->setUF($nota->getEmitente()->getEndereco()->
292 2
                getMunicipio()->getEstado()->getUF());
293 2
            $inutilizacao->setAmbiente($nota->getAmbiente());
294 2
            $inutilizacao->setModelo($nota->getModelo());
295
        }
296 4
        $dom = $inutilizacao->getNode()->ownerDocument;
297 3
        $dom = $inutilizacao->assinar($dom);
298 3
        $dom = $inutilizacao->envia($dom);
299 2
        $this->setDocumento($dom);
300 2
        return $inutilizacao;
301
    }
302
    
303 5
    private function consulta()
304
    {
305 5
        $nota = $this->getNota();
306 5
        $agente = $this->getAgente();
307 5
        if (is_null($agente)) {
308 3
            if (is_null($nota)) {
309 1
                throw new \Exception('A nota não foi informada na tarefa de consulta "'.$this->getID().'"', 404);
310
            }
311 2
            $agente = new Situacao();
312 2
            $agente->setChave($nota->getID());
313 2
            $this->setAgente($agente);
314 2
        } elseif (!($agente instanceof Situacao) && !($agente instanceof Recibo)) {
315 1
            throw new \Exception('O agente informado não é uma consulta de situação e nem um recibo', 500);
316
        }
317 3
        if (!is_null($nota)) {
318 3
            $agente->setAmbiente($nota->getAmbiente());
319 3
            $agente->setModelo($nota->getModelo());
320
        }
321 3
        $retorno = $agente->consulta($this->getNota());
322 3
        if ($agente->isCancelado()) {
323
            // TODO: carregar assinatura do XML para evitar usar outro certificado
324 1
            $dom = $retorno->assinar();
325 1
            $dom = $retorno->validar($dom);
326
            // $dom = $retorno->getNode()->ownerDocument; // descomentar essa linha quando implementar
327
            // TODO: Fim do problema de assinatura
328 1
            $dom = $retorno->addInformacao($dom);
329 1
            $this->setDocumento($dom);
330 1
            $retorno = $retorno->getInformacao();
331
        }
332 3
        return $retorno;
333
    }
334
}
335