Passed
Pull Request — master (#921)
by
unknown
08:01
created

Complements::addEnvEventoProtocol()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 41
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
eloc 29
dl 0
loc 41
ccs 0
cts 31
cp 0
rs 9.456
c 0
b 0
f 0
cc 4
nc 6
nop 2
crap 20
1
<?php
2
3
namespace NFePHP\NFe;
4
5
use NFePHP\Common\Strings;
6
use NFePHP\NFe\Common\Standardize;
7
use NFePHP\NFe\Exception\DocumentsException;
8
use DOMDocument;
9
10
class Complements
11
{
12
    protected static $urlPortal = 'http://www.portalfiscal.inf.br/nfe';
13
14
    /**
15
     * Authorize document adding his protocol
16
     * @param string $request
17
     * @param string $response
18
     * @return string
19
     */
20 2
    public static function toAuthorize($request, $response)
21
    {
22 2
        $st = new Standardize();
23 2
        $key = ucfirst($st->whichIs($request));
24 2
        if ($key != 'NFe' && $key != 'EnvEvento' && $key != 'InutNFe') {
25
            //wrong document, this document is not able to recieve a protocol
26
            throw DocumentsException::wrongDocument(0, $key);
27
        }
28 2
        $func = "add" . $key . "Protocol";
29 2
        return self::$func($request, $response);
30
    }
31
32
    /**
33
     * Add tags B2B, as example ANFAVEA
34
     * @param  string $nfe xml nfe string content
35
     * @param  string $b2b xml b2b string content
36
     * @param  string $tagB2B name B2B tag default 'NFeB2BFin' from ANFAVEA
37
     * @return string
38
     * @throws \InvalidArgumentException
39
     */
40
    public static function b2bTag($nfe, $b2b, $tagB2B = 'NFeB2BFin')
41
    {
42
        $domnfe = new DOMDocument('1.0', 'UTF-8');
43
        $domnfe->preserveWhiteSpace = false;
44
        $domnfe->formatOutput = false;
45
        $domnfe->loadXML($nfe);
46
        $nodenfe = $domnfe->getElementsByTagName('nfeProc')->item(0);
47
        if (empty($nodenfe)) {
48
            //not is NFe or dont protocoladed doc
49
            throw DocumentsException::wrongDocument(1);
50
        }
51
        //carrega o arquivo B2B
52
        $domb2b = new DOMDocument('1.0', 'UTF-8');
53
        $domb2b->preserveWhiteSpace = false;
54
        $domb2b->formatOutput = false;
55
        $domb2b->loadXML($b2b);
56
        $nodeb2b = $domnfe->getElementsByTagName($tagB2B)->item(0);
57
        if (empty($nodeb2b)) {
58
            //xml is not protocoladed or dont is a NFe
59
            throw DocumentsException::wrongDocument(2);
60
        }
61
        //cria a NFe processada com a tag do protocolo
62
        $procb2b = new DOMDocument('1.0', 'UTF-8');
63
        $procb2b->preserveWhiteSpace = false;
64
        $procb2b->formatOutput = false;
65
        //cria a tag nfeProc
66
        $nfeProcB2B = $procb2b->createElement('nfeProcB2B');
67
        $procb2b->appendChild($nfeProcB2B);
68
        //inclui a tag NFe
69
        $node1 = $procb2b->importNode($nodenfe, true);
70
        $nfeProcB2B->appendChild($node1);
71
        //inclui a tag NFeB2BFin
72
        $node2 = $procb2b->importNode($nodeb2b, true);
73
        $nfeProcB2B->appendChild($node2);
74
        $nfeb2bXML = $procb2b->saveXML();
75
        $nfeb2bXMLString = str_replace(array("\n","\r","\s"), '', $nfeb2bXML);
76
        return (string) $nfeb2bXMLString;
77
    }
78
79
    /**
80
     * Add cancel protocol to a autorized NFe
81
     * if event is not a cancellation will return
82
     * the same autorized NFe passing
83
     * NOTE: This action is not necessary, I use only for my needs to
84
     *       leave the NFe marked as Canceled in order to avoid mistakes
85
     *       after its cancellation.
86
     * @param  string $nfe content of autorized NFe XML
87
     * @param  string $cancelamento content of SEFAZ response
88
     * @return string
89
     * @throws \InvalidArgumentException
90
     */
91
    public static function cancelRegister($nfe, $cancelamento)
92
    {
93
        $procXML = $nfe;
0 ignored issues
show
Unused Code introduced by
The assignment to $procXML is dead and can be removed.
Loading history...
94
        $domnfe = new DOMDocument('1.0', 'utf-8');
95
        $domnfe->formatOutput = false;
96
        $domnfe->preserveWhiteSpace = false;
97
        $domnfe->loadXML($nfe);
98
        $nfeproc = $domnfe->getElementsByTagName('nfeProc')->item(0);
0 ignored issues
show
Unused Code introduced by
The assignment to $nfeproc is dead and can be removed.
Loading history...
99
        $proNFe = $domnfe->getElementsByTagName('protNFe')->item(0);
100
        if (empty($proNFe)) {
101
            //not protocoladed NFe
102
            throw DocumentsException::wrongDocument(1);
103
        }
104
        $chaveNFe = $proNFe->getElementsByTagName('chNFe')->item(0)->nodeValue;
105
        $domcanc = new DOMDocument('1.0', 'utf-8');
106
        $domcanc->formatOutput = false;
107
        $domcanc->preserveWhiteSpace = false;
108
        $domcanc->loadXML($cancelamento);
109
        $eventos = $domcanc->getElementsByTagName('retEvento');
110
        foreach ($eventos as $evento) {
111
            $infEvento = $evento->getElementsByTagName('infEvento')->item(0);
112
            $cStat = $infEvento->getElementsByTagName('cStat')
113
                ->item(0)
114
                ->nodeValue;
115
            $nProt = $infEvento->getElementsByTagName('nProt')
0 ignored issues
show
Unused Code introduced by
The assignment to $nProt is dead and can be removed.
Loading history...
116
                ->item(0)
117
                ->nodeValue;
118
            $chaveEvento = $infEvento->getElementsByTagName('chNFe')
119
                ->item(0)
120
                ->nodeValue;
121
            $tpEvento = $infEvento->getElementsByTagName('tpEvento')
122
                ->item(0)
123
                ->nodeValue;
124
            if (
125
                in_array($cStat, ['135', '136', '155'])
126
                && ($tpEvento == Tools::EVT_CANCELA
127
                    || $tpEvento == Tools::EVT_CANCELASUBSTITUICAO
128
                )
129
                && $chaveEvento == $chaveNFe
130
            ) {
131
                $node = $domnfe->importNode($evento, true);
132
                $domnfe->documentElement->appendChild($node);
133
                break;
134
            }
135
        }
136
        return $domnfe->saveXML();
137
    }
138
139
    /**
140
     * Authorize Inutilization of numbers
141
     * @param string $request
142
     * @param string $response
143
     * @return string
144
     * @throws \InvalidArgumentException
145
     */
146
    protected static function addInutNFeProtocol($request, $response)
147
    {
148
        $req = new DOMDocument('1.0', 'UTF-8');
149
        $req->preserveWhiteSpace = false;
150
        $req->formatOutput = false;
151
        $req->loadXML($request);
152
        $inutNFe = $req->getElementsByTagName('inutNFe')->item(0);
153
        $versao = $inutNFe->getAttribute("versao");
154
        $infInut = $req->getElementsByTagName('infInut')->item(0);
155
        $tpAmb = $infInut->getElementsByTagName('tpAmb')->item(0)->nodeValue;
156
        $cUF = !empty($infInut->getElementsByTagName('cUF')->item(0)->nodeValue)
157
            ? $infInut->getElementsByTagName('cUF')->item(0)->nodeValue : '';
158
        $ano = $infInut->getElementsByTagName('ano')->item(0)->nodeValue;
159
        $cnpj = $infInut->getElementsByTagName('CNPJ')->item(0)->nodeValue;
160
        $mod = $infInut->getElementsByTagName('mod')->item(0)->nodeValue;
161
        $serie = $infInut->getElementsByTagName('serie')->item(0)->nodeValue;
162
        $nNFIni = $infInut->getElementsByTagName('nNFIni')->item(0)->nodeValue;
163
        $nNFFin = $infInut->getElementsByTagName('nNFFin')->item(0)->nodeValue;
164
165
        $ret = new DOMDocument('1.0', 'UTF-8');
166
        $ret->preserveWhiteSpace = false;
167
        $ret->formatOutput = false;
168
        $ret->loadXML($response);
169
        $retInutNFe = $ret->getElementsByTagName('retInutNFe')->item(0);
170
        if (!isset($retInutNFe)) {
171
            throw DocumentsException::wrongDocument(3, "&lt;retInutNFe;");
172
        }
173
        $retversao = $retInutNFe->getAttribute("versao");
174
        $retInfInut = $ret->getElementsByTagName('infInut')->item(0);
175
        $cStat = $retInfInut->getElementsByTagName('cStat')->item(0)->nodeValue;
176
        $xMotivo = $retInfInut->getElementsByTagName('xMotivo')->item(0)->nodeValue;
177
        if ($cStat != 102) {
178
            throw DocumentsException::wrongDocument(4, "[$cStat] $xMotivo.");
179
        }
180
        $rettpAmb = $retInfInut->getElementsByTagName('tpAmb')->item(0)->nodeValue;
181
        $retcUF = !empty($retInfInut->getElementsByTagName('cUF')->item(0)->nodeValue)
182
            ? $retInfInut->getElementsByTagName('cUF')->item(0)->nodeValue : $cUF;
183
        $retano = $retInfInut->getElementsByTagName('ano')->item(0)->nodeValue;
184
        $retcnpj = $retInfInut->getElementsByTagName('CNPJ')->item(0)->nodeValue;
185
        $retmod = $retInfInut->getElementsByTagName('mod')->item(0)->nodeValue;
186
        $retserie = $retInfInut->getElementsByTagName('serie')->item(0)->nodeValue;
187
        $retnNFIni = $retInfInut->getElementsByTagName('nNFIni')->item(0)->nodeValue;
188
        $retnNFFin = $retInfInut->getElementsByTagName('nNFFin')->item(0)->nodeValue;
189
        if (
190
            $versao != $retversao ||
191
            $tpAmb != $rettpAmb ||
192
            $cUF != $retcUF ||
193
            $ano != $retano ||
194
            $cnpj != $retcnpj ||
195
            $mod != $retmod ||
196
            $serie != $retserie ||
197
            $nNFIni != $retnNFIni ||
198
            $nNFFin != $retnNFFin
199
        ) {
200
            throw DocumentsException::wrongDocument(5);
201
        }
202
        return self::join(
203
            $req->saveXML($inutNFe),
204
            $ret->saveXML($retInutNFe),
205
            'ProcInutNFe',
206
            $versao
207
        );
208
    }
209
210
    /**
211
     * Authorize NFe
212
     * @param string $request
213
     * @param string $response
214
     * @return string
215
     * @throws \InvalidArgumentException
216
     */
217 2
    protected static function addNFeProtocol($request, $response)
218
    {
219 2
        $req = new DOMDocument('1.0', 'UTF-8');
220 2
        $req->preserveWhiteSpace = false;
221 2
        $req->formatOutput = false;
222 2
        $req->loadXML($request);
223
224 2
        $nfe = $req->getElementsByTagName('NFe')->item(0);
225 2
        $infNFe = $req->getElementsByTagName('infNFe')->item(0);
226 2
        $versao = $infNFe->getAttribute("versao");
227 2
        $chave = preg_replace('/[^0-9]/', '', $infNFe->getAttribute("Id"));
228 2
        $digNFe = $req->getElementsByTagName('DigestValue')
229 2
            ->item(0)
230 2
            ->nodeValue;
231
232 2
        $ret = new DOMDocument('1.0', 'UTF-8');
233 2
        $ret->preserveWhiteSpace = false;
234 2
        $ret->formatOutput = false;
235 2
        $ret->loadXML($response);
236 2
        $retProt = $ret->getElementsByTagName('protNFe')->length > 0 ? $ret->getElementsByTagName('protNFe') : null;
237 2
        if ($retProt === null) {
238
            throw DocumentsException::wrongDocument(3, "&lt;protNFe&gt;");
239
        }
240 2
        $digProt = null;
241 2
        foreach ($retProt as $rp) {
242 2
            $infProt = $rp->getElementsByTagName('infProt')->item(0);
243 2
            $cStat = $infProt->getElementsByTagName('cStat')->item(0)->nodeValue;
244 2
            $xMotivo = $infProt->getElementsByTagName('xMotivo')->item(0)->nodeValue;
245 2
            $dig = $infProt->getElementsByTagName("digVal")->item(0);
246 2
            $key = $infProt->getElementsByTagName("chNFe")->item(0)->nodeValue;
247 2
            if (isset($dig)) {
248 2
                $digProt = $dig->nodeValue;
249 2
                if ($digProt == $digNFe && $chave == $key) {
250
                    //100 Autorizado
251
                    //150 Autorizado fora do prazo
252
                    //110 Uso Denegado
253
                    //205 NFe Denegada
254
                    //301 Uso denegado por irregularidade fiscal do emitente
255
                    //302 Uso denegado por irregularidade fiscal do destinatário
256
                    //303 Uso Denegado Destinatario nao habilitado a operar na UF
257 1
                    $cstatpermit = ['100', '150', '110', '205', '301', '302', '303'];
258 1
                    if (!in_array($cStat, $cstatpermit)) {
259
                        throw DocumentsException::wrongDocument(4, "[$cStat] $xMotivo");
260
                    }
261 1
                    return self::join(
262 1
                        $req->saveXML($nfe),
263 1
                        $ret->saveXML($rp),
264 1
                        'nfeProc',
265 2
                        $versao
266
                    );
267
                }
268
            }
269
        }
270 1
        if (empty($digProt)) {
271
            $prot = $ret->getElementsByTagName('protNFe')->item(0);
272
            $cStat = $prot->getElementsByTagName('cStat')->item(0)->nodeValue;
273
            $xMotivo = $prot->getElementsByTagName('xMotivo')->item(0)->nodeValue;
274
            throw DocumentsException::wrongDocument(18, "[{$cStat}] {$xMotivo}");
275
        }
276 1
        if ($digNFe !== $digProt) {
277 1
            throw DocumentsException::wrongDocument(5, "Os digest são diferentes [{$chave}]");
278
        }
279
        return $req->saveXML();
280
    }
281
282
    /**
283
     * Authorize Event
284
     * @param string $request
285
     * @param string $response
286
     * @return string
287
     * @throws \InvalidArgumentException
288
     */
289
    protected static function addEnvEventoProtocol($request, $response)
290
    {
291
        $ev = new \DOMDocument('1.0', 'UTF-8');
292
        $ev->preserveWhiteSpace = false;
293
        $ev->formatOutput = false;
294
        $ev->loadXML($request);
295
        //extrai numero do lote do envio
296
        $envLote = $ev->getElementsByTagName('idLote')->item(0)->nodeValue;
297
        //extrai tag evento do xml origem (solicitação)
298
        $event = $ev->getElementsByTagName('evento')->item(0);
299
        $versao = $event->getAttribute('versao');
300
301
        $ret = new \DOMDocument('1.0', 'UTF-8');
302
        $ret->preserveWhiteSpace = false;
303
        $ret->formatOutput = false;
304
        $ret->loadXML($response);
305
        //extrai numero do lote da resposta
306
        $resLote = $ret->getElementsByTagName('idLote')->item(0)->nodeValue;
307
        //extrai a rag retEvento da resposta (retorno da SEFAZ)
308
        $retEv = $ret->getElementsByTagName('retEvento')->item(0);
309
        $cStat  = $retEv->getElementsByTagName('cStat')->item(0)->nodeValue;
310
        $xMotivo = $retEv->getElementsByTagName('xMotivo')->item(0)->nodeValue;
311
        $tpEvento = $retEv->getElementsByTagName('tpEvento')->item(0)->nodeValue;
312
        $cStatValids = ['135', '136'];
313
        if ($tpEvento == Tools::EVT_CANCELA) {
314
            $cStatValids[] = '155';
315
        }
316
        if (!in_array($cStat, $cStatValids)) {
317
            throw DocumentsException::wrongDocument(4, "[$cStat] $xMotivo");
318
        }
319
        if ($resLote !== $envLote) {
320
            throw DocumentsException::wrongDocument(
321
                5,
322
                "Os numeros de lote dos documentos são diferentes."
323
            );
324
        }
325
        return self::join(
326
            $ev->saveXML($event),
327
            $ret->saveXML($retEv),
328
            'procEventoNFe',
329
            $versao
330
        );
331
    }
332
333
    /**
334
     * Join the pieces of the source document with those of the answer
335
     * @param string $first
336
     * @param string $second
337
     * @param string $nodename
338
     * @param string $versao
339
     * @return string
340
     */
341 1
    protected static function join($first, $second, $nodename, $versao)
342
    {
343
        $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
344 1
                . "<$nodename versao=\"$versao\" "
345 1
                . "xmlns=\"" . self::$urlPortal . "\">";
346 1
        $xml .= $first;
347 1
        $xml .= $second;
348 1
        $xml .= "</$nodename>";
349 1
        return $xml;
350
    }
351
}
352