Passed
Pull Request — master (#921)
by
unknown
10:53 queued 08:00
created

Convert::isNFe()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0987

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 12
ccs 7
cts 9
cp 0.7778
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 3.0987
1
<?php
2
3
/**
4
 * Converts NFe from text format to xml
5
 * @category  API
6
 * @package   NFePHP\NFe
7
 * @copyright NFePHP Copyright (c) 2008-2019
8
 * @license   http://www.gnu.org/licenses/lgpl.txt LGPLv3+
9
 * @license   https://opensource.org/licenses/MIT MIT
10
 * @license   http://www.gnu.org/licenses/gpl.txt GPLv3+
11
 * @author    Roberto L. Machado <linux.rlm at gmail dot com>
12
 * @link      http://github.com/nfephp-org/sped-nfe for the canonical source repository
13
 */
14
15
namespace NFePHP\NFe;
16
17
use NFePHP\NFe\Common\ValidTXT;
18
use NFePHP\NFe\Exception\DocumentsException;
19
use NFePHP\NFe\Exception\ParserException;
20
use NFePHP\NFe\Exception\RuntimeException;
21
use NFePHP\NFe\Factories\Parser;
22
23
class Convert
24
{
25
    const LOCAL = "LOCAL";
26
    const LOCAL_V12 = "LOCAL_V12";
27
    const SEBRAE = "SEBRAE";
28
29
    protected $txt;
30
    protected $dados;
31
    protected $numNFe = 1;
32
    protected $notas;
33
    protected $layouts = [];
34
    protected $xmls = [];
35
    protected $baselayout;
36
37
    /**
38
     * Constructor method
39
     * @param string $txt
40
     * @param string $baselayout
41
     */
42 1
    public function __construct($txt = '', $baselayout = self::LOCAL)
43
    {
44 1
        $this->baselayout = $baselayout;
45 1
        if (!empty($txt)) {
46 1
            $this->txt = trim($txt);
47
        }
48 1
    }
49
50
    /**
51
     * Static method to convert Txt to Xml
52
     * @param string $txt
53
     * @param string $baselayout
54
     * @return array
55
     */
56
    public static function parse($txt, $baselayout = self::LOCAL)
57
    {
58
        $conv = new static($txt, $baselayout);
59
        return $conv->toXml();
60
    }
61
62
    /**
63
     * Convert all nfe in XML, one by one
64
     * @return array
65
     * @throws \NFePHP\NFe\Exception\DocumentsException
66
     */
67 1
    public function toXml()
68
    {
69
        //$txt = Strings::removeSomeAlienCharsfromTxt($this->txt);
70
71 1
        if (!$this->isNFe($this->txt)) {
72
            throw DocumentsException::wrongDocument(12, '');
73
        }
74 1
        $this->notas = $this->sliceNotas($this->dados);
75 1
        $this->checkQtdNFe();
76 1
        $this->validNotas();
77 1
        $i = 0;
78 1
        foreach ($this->notas as $nota) {
79 1
            $version = $this->layouts[$i];
80 1
            $parser = new Parser($version, $this->baselayout);
81
            try {
82 1
                $this->xmls[] = $parser->toXml($nota);
83
            } catch (\Exception $e) {
84
                if ($errors = $parser->getErrors()) {
85
                    throw new ParserException(implode(', ', $errors));
86
                } else {
87
                    throw new RuntimeException($e->getMessage());
88
                }
89
            }
90 1
            $i++;
91
        }
92 1
        return $this->xmls;
93
    }
94
95
    /**
96
     * Check if it is an NFe in TXT format
97
     * @param string $txt
98
     * @return boolean
99
     */
100 1
    protected function isNFe($txt)
101
    {
102 1
        if (empty($txt)) {
103
            throw DocumentsException::wrongDocument(15, '');
104
        }
105 1
        $this->dados = explode("\n", $txt);
106 1
        $fields = explode('|', $this->dados[0]);
107 1
        if ($fields[0] == 'NOTAFISCAL') {
108 1
            $this->numNFe = (int) $fields[1];
109 1
            return true;
110
        }
111
        return false;
112
    }
113
114
    /**
115
     * Separate nfe into elements of an array
116
     * @param  array $array
117
     * @return array
118
     */
119 1
    protected function sliceNotas($array)
120
    {
121 1
        $aNotas = [];
122 1
        $annu = explode('|', $array[0]);
123 1
        $numnotas = $annu[1];
124 1
        unset($array[0]);
125 1
        if ($numnotas == 1) {
126 1
            $aNotas[] = $array;
127 1
            return $aNotas;
128
        }
129
        $iCount = 0;
130
        $xCount = 0;
131
        $resp = [];
132
        foreach ($array as $linha) {
133
            if (substr($linha, 0, 2) == 'A|') {
134
                $resp[$xCount]['init'] = $iCount;
135
                if ($xCount > 0) {
136
                    $resp[$xCount - 1]['fim'] = $iCount;
137
                }
138
                $xCount += 1;
139
            }
140
            $iCount += 1;
141
        }
142
        $resp[$xCount - 1]['fim'] = $iCount;
143
        foreach ($resp as $marc) {
144
            $length = $marc['fim'] - $marc['init'];
145
            $aNotas[] = array_slice($array, $marc['init'], $length, false);
146
        }
147
        return $aNotas;
148
    }
149
150
    /**
151
     * Verify number of NFe declared
152
     * If different throws an exception
153
     * @throws \NFePHP\NFe\Exception\DocumentsException
154
     */
155 1
    protected function checkQtdNFe()
156
    {
157 1
        $num = count($this->notas);
158 1
        if ($num != $this->numNFe) {
159
            throw DocumentsException::wrongDocument(13, '');
160
        }
161 1
    }
162
163
    /**
164
     * Valid all NFes in txt and get layout version for each nfe
165
     */
166 1
    protected function validNotas()
167
    {
168 1
        foreach ($this->notas as $nota) {
169 1
            $this->loadLayoutsVersions($nota);
170 1
            $this->isValidTxt($nota);
171
        }
172 1
    }
173
174
    /**
175
     * Read and set all layouts versions in NFes
176
     * @param array $nota
177
     */
178 1
    protected function loadLayoutsVersions($nota)
179
    {
180 1
        if (empty($nota)) {
181
            throw DocumentsException::wrongDocument(17, '');
182
        }
183 1
        foreach ($nota as $campo) {
184 1
            $fields = explode('|', $campo);
185 1
            if ($fields[0] == 'A') {
186 1
                $this->layouts[] = $fields[1];
187 1
                break;
188
            }
189
        }
190 1
    }
191
192
    /**
193
     * Valid txt structure
194
     * @param array $nota
195
     * @throws \NFePHP\NFe\Exception\DocumentsException
196
     */
197 1
    protected function isValidTxt($nota)
198
    {
199 1
        $errors = ValidTXT::isValid(implode("\n", $nota), $this->baselayout);
200 1
        if (!empty($errors)) {
201
            throw DocumentsException::wrongDocument(14, implode("\n", $errors));
202
        }
203 1
    }
204
}
205