Completed
Push — master ( 64c34c...73f724 )
by Roberto
09:18 queued 07:04
created

Tools::enviarLoteEventos()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 50

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 50
ccs 0
cts 45
cp 0
rs 8.4686
c 0
b 0
f 0
cc 6
nc 6
nop 2
crap 42
1
<?php
2
3
namespace NFePHP\EFDReinf;
4
5
/**
6
 * Classe Tools, performs communication with the EFDReinf webservice
7
 *
8
 * @category  Library
9
 * @package   NFePHP\EFDReinf\Tools
10
 * @copyright Copyright (c) 2017-2021
11
 * @license   https://www.gnu.org/licenses/lgpl-3.0.txt LGPLv3
12
 * @license   https://www.gnu.org/licenses/gpl-3.0.txt GPLv3
13
 * @license   https://opensource.org/licenses/mit-license.php MIT
14
 * @author    Roberto L. Machado <linux.rlm at gmail dot com>
15
 * @link      http://github.com/nfephp-org/sped-efdreinf for the canonical source repository
16
 */
17
use NFePHP\Common\Certificate;
18
use NFePHP\Common\Validator;
19
use NFePHP\EFDReinf\Common\Tools as ToolsBase;
20
use NFePHP\EFDReinf\Common\FactoryInterface;
21
use NFePHP\EFDReinf\Common\Soap\SoapCurl;
22
use NFePHP\EFDReinf\Common\Soap\SoapInterface;
23
use NFePHP\EFDReinf\Exception\ProcessException;
24
use stdClass;
25
use NFePHP\EFDReinf\Common\Factory;
26
27
class Tools extends ToolsBase
28
{
29
    const CONSULTA_CONSOLIDADA = 1;
30
    const CONSULTA_R1000 = 2;
31
    const CONSULTA_R1070 = 3;
32
    const CONSULTA_R2010 = 4;
33
    const CONSULTA_R2020 = 5;
34
    const CONSULTA_R2030 = 6;
35
    const CONSULTA_R2040 = 7;
36
    const CONSULTA_R2050 = 8;
37
    const CONSULTA_R2055 = 13;
38
    const CONSULTA_R2060 = 9;
39
    const CONSULTA_R2098 = 10;
40
    const CONSULTA_R2099 = 11;
41
    const CONSULTA_R3010 = 12;
42
    const CONSULTA_FECHAMENTO = 14;
43
44
    /**
45
     * @var string
46
     */
47
    public $lastRequest;
48
    /**
49
     * @var string
50
     */
51
    public $lastResponse;
52
    /**
53
     * @var SoapInterface
54
     */
55
    public $soap;
56
    /**
57
     * @var string
58
     */
59
    public $namespace = 'http://sped.fazenda.gov.br/';
60
    /**
61
     * @var array
62
     */
63
    protected $soapnamespaces = [
64
        'xmlns:soapenv' => "http://schemas.xmlsoap.org/soap/envelope/",
65
        'xmlns:sped'=> "http://sped.fazenda.gov.br/"
66
    ];
67
    /**
68
     * @var array
69
     */
70
    protected $uri = [
71
        '1' => 'https://reinf.receita.fazenda.gov.br/WsREINF/RecepcaoLoteReinf.svc',
72
        '2' => 'https://preprodefdreinf.receita.fazenda.gov.br/WsREINF/RecepcaoLoteReinf.svc'
73
74
    ];
75
    /**
76
     * @var array
77
     */
78
    protected $uriconsulta = [
79
        '1' => 'https://reinf.receita.fazenda.gov.br/WsReinfConsultas/ConsultasReinf.svc',
80
        '2' => 'https://preprodefdreinf.receita.fazenda.gov.br/WsReinfConsultas/ConsultasReinf.svc'
81
    ];
82
83
    /**
84
     * @var string
85
     */
86
    protected $action;
87
    /**
88
     * @var string
89
     */
90
    protected $method;
91
92
    /**
93
     * Constructor
94
     * @param string $config
95
     * @param Certificate $certificate
96
     */
97
    public function __construct($config, Certificate $certificate)
98
    {
99
        parent::__construct($config, $certificate);
100
    }
101
102
    /**
103
     * SOAP communication dependency injection
104
     * @param SoapInterface $soap
105
     */
106
    public function loadSoapClass(SoapInterface $soap)
107
    {
108
        $this->soap = $soap;
109
    }
110
111
    /**
112
     * Run EFD-REINF Query
113
     * @param integer $mod
114
     * @param stdClass $std
115
     * @throws ProcessException
116
     */
117
    public function consultar($mod, stdClass $std = null)
118
    {
119
        if (isset($std)) {
120
            //converte os nomes das propriedades do stdClass para caixa baixa
121
            $std = Factory::propertiesToLower($std);
122
        }
123
        switch ($mod) {
124
            case 1:
125
                $evt = 0;
0 ignored issues
show
Unused Code introduced by
$evt is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
126
                $request = $this->consultConsolidadas($std);
0 ignored issues
show
Bug introduced by
It seems like $std defined by parameter $std on line 117 can be null; however, NFePHP\EFDReinf\Tools::consultConsolidadas() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
127
                break;
128
            case 2:
129
                $evt = 1000;
130
                $request = $this->consultR1($evt);
131
                break;
132
            case 3:
133
                $evt = 1070;
134
                $request = $this->consultR1($evt);
135
                break;
136
            case 4:
137
                $evt = 2010;
138
                $request = $this->consultR2010($evt, $std);
0 ignored issues
show
Bug introduced by
It seems like $std defined by parameter $std on line 117 can be null; however, NFePHP\EFDReinf\Tools::consultR2010() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
139
                break;
140
            case 5:
141
                $evt = 2020;
142
                $request = $this->consultR2020($evt, $std);
0 ignored issues
show
Bug introduced by
It seems like $std defined by parameter $std on line 117 can be null; however, NFePHP\EFDReinf\Tools::consultR2020() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
143
                break;
144
            case 6:
145
                $evt = 2030;
146
                $request = $this->consultR20($evt, $std);
0 ignored issues
show
Bug introduced by
It seems like $std defined by parameter $std on line 117 can be null; however, NFePHP\EFDReinf\Tools::consultR20() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
147
                break;
148
            case 7:
149
                $evt = 2040;
150
                $request = $this->consultR20($evt, $std);
0 ignored issues
show
Bug introduced by
It seems like $std defined by parameter $std on line 117 can be null; however, NFePHP\EFDReinf\Tools::consultR20() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
151
                break;
152
            case 8:
153
                $evt = 2050;
154
                $request = $this->consultR20($evt, $std);
0 ignored issues
show
Bug introduced by
It seems like $std defined by parameter $std on line 117 can be null; however, NFePHP\EFDReinf\Tools::consultR20() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
155
                break;
156
            case 9:
157
                $evt = 2060;
158
                $request = $this->consultR2060($evt, $std);
0 ignored issues
show
Bug introduced by
It seems like $std defined by parameter $std on line 117 can be null; however, NFePHP\EFDReinf\Tools::consultR2060() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
159
                break;
160
            case 10:
161
                $evt = 2098;
162
                $request = $this->consultR209($evt, $std);
0 ignored issues
show
Bug introduced by
It seems like $std defined by parameter $std on line 117 can be null; however, NFePHP\EFDReinf\Tools::consultR209() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
163
                break;
164
            case 11:
165
                $evt = 2099;
166
                $request = $this->consultR209($evt, $std);
0 ignored issues
show
Bug introduced by
It seems like $std defined by parameter $std on line 117 can be null; however, NFePHP\EFDReinf\Tools::consultR209() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
167
                break;
168
            case 12:
169
                $evt = 3010;
170
                $request = $this->consultR3010($evt, $std);
0 ignored issues
show
Bug introduced by
It seems like $std defined by parameter $std on line 117 can be null; however, NFePHP\EFDReinf\Tools::consultR3010() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
171
                break;
172
            case 13:
173
                $evt = 2055;
174
                $request = $this->consultR2055($evt, $std);
0 ignored issues
show
Bug introduced by
It seems like $std defined by parameter $std on line 117 can be null; however, NFePHP\EFDReinf\Tools::consultR2055() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
175
                break;
176
            case 14:
177
                $request = $this->consultFechamento($std);
0 ignored issues
show
Bug introduced by
It seems like $std defined by parameter $std on line 117 can be null; however, NFePHP\EFDReinf\Tools::consultFechamento() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
178
                break;
179
            default:
180
                throw ProcessException::wrongArgument(2003, '');
181
        }
182
        $this->lastResponse = $this->sendRequest($request);
183
        return $this->lastResponse;
184
    }
185
186
    /**
187
     * Consultation of consolidated information
188
     * @param stdClass $std
189
     * @return string
190
     */
191
    public function consultConsolidadas(stdClass $std)
192
    {
193
        $properties = [
194
            'numeroprotocolofechamento' => [
195
                'required' => true,
196
                'type' => 'string',
197
                'regex' => ''
198
            ],
199
        ];
200
        $this->validInputParameters($properties, $std);
201
202
        $this->method = "ConsultaInformacoesConsolidadas";
203
        $this->action = "{$this->namespace}ConsultasReinf/{$this->method}";
204
        $request = "<sped:{$this->method}>"
205
            . "<sped:tipoInscricaoContribuinte>{$this->tpInsc}</sped:tipoInscricaoContribuinte>"
206
            . "<sped:numeroInscricaoContribuinte>{$this->nrInsc}</sped:numeroInscricaoContribuinte>"
207
            . "<sped:numeroProtocoloFechamento>{$std->numeroprotocolofechamento}</sped:numeroProtocoloFechamento>"
208
            . "</sped:{$this->method}>";
209
        return $request;
210
    }
211
    
212
    /**
213
     * Consultation of Fachamento
214
     * @param stdClass $std
215
     * @return string
216
     */
217
    public function consultFechamento(stdClass $std)
218
    {
219
        $properties = [
220
            'numeroprotocolofechamento' => [
221
                'required' => true,
222
                'type' => 'string',
223
                'regex' => ''
224
            ],
225
        ];
226
        $this->validInputParameters($properties, $std);
227
228
        $this->method = "ConsultaResultadoFechamento2099";
229
        $this->action = "{$this->namespace}ConsultasReinf/{$this->method}";
230
        $request = "<sped:{$this->method}>"
231
            . "<sped:tpInsc>{$this->tpInsc}</sped:tpInsc>"
232
            . "<sped:nrInsc>{$this->nrInsc}</sped:nrInsc>"
233
            . "<sped:numeroProtocoloFechamento>{$std->numeroprotocolofechamento}</sped:numeroProtocoloFechamento>"
234
            . "</sped:{$this->method}>";
235
        return $request;
236
    }
237
238
    /**
239
     * Consultation R1000 and R1070
240
     * @param integer $evt
241
     * @return string
242
     */
243
    protected function consultR1($evt)
244
    {
245
        $this->method = "ConsultaReciboEvento{$evt}";
246
        $this->action = "{$this->namespace}ConsultasReinf/{$this->method}";
247
        $request = "<sped:{$this->method}>"
248
            . "<sped:tipoEvento>{$evt}</sped:tipoEvento>"
249
            . "<sped:tpInsc>{$this->tpInsc}</sped:tpInsc>"
250
            . "<sped:nrInsc>{$this->nrInsc}</sped:nrInsc>"
251
            . "</sped:{$this->method}>";
252
        return $request;
253
    }
254
255
    /**
256
     * Consultation R2010
257
     * @param integer $evt
258
     * @param stdClass $std
259
     * @return string
260
     */
261
    protected function consultR2010($evt, $std)
262
    {
263
        $properties = [
264
            'perapur' => [
265
                'required' => false,
266
                'type' => ['string',"null"],
267
                'regex' => '^(19[0-9][0-9]|2[0-9][0-9][0-9])[-](0?[1-9]|1[0-2])$'
268
            ],
269
            'tpinscestab' => [
270
                'required' => true,
271
                'type' => 'integer',
272
                'min' => 1,
273
                'max' => 2
274
            ],
275
            'nrinscestab' => [
276
                'required' => true,
277
                'type' => 'string',
278
                'regex' => '^[0-9]{11,14}$'
279
            ],
280
            'cnpjprestador' => [
281
                'required' => true,
282
                'type' => 'string',
283
                'regex' => '^[0-9]{14}$'
284
            ],
285
        ];
286
        $this->validInputParameters($properties, $std);
287
288
        $this->method = "ConsultaReciboEvento{$evt}";
289
        $this->action = "{$this->namespace}ConsultasReinf/{$this->method}";
290
        $request = "<sped:{$this->method}>"
291
            . "<sped:tipoEvento>{$evt}</sped:tipoEvento>"
292
            . "<sped:tpInsc>{$this->tpInsc}</sped:tpInsc>"
293
            . "<sped:nrInsc>{$this->nrInsc}</sped:nrInsc>";
294
        if (!empty($std->perapur)) {
295
            $request .=  "<sped:perApur>{$std->perapur}</sped:perApur>";
296
        }
297
        $request .= "<sped:tpInscEstab>{$std->tpinscestab}</sped:tpInscEstab>"
298
            . "<sped:nrInscEstab>"
299
                . str_pad($std->nrinscestab, 14, '0', STR_PAD_LEFT)
300
                . "</sped:nrInscEstab>"
301
            . "<sped:cnpjPrestador>"
302
                . str_pad($std->cnpjprestador, 14, '0', STR_PAD_LEFT)
303
                . "</sped:cnpjPrestador>"
304
            . "</sped:{$this->method}>";
305
        return $request;
306
    }
307
308
    /**
309
     * Consultation R2020
310
     * @param integer $evt
311
     * @param stdClass $std
312
     * @return string
313
     */
314
    protected function consultR2020($evt, $std)
315
    {
316
        $properties = [
317
            'perapur' => [
318
                'required' => false,
319
                'type' => ['string',"null"],
320
                'regex' => '^(19[0-9][0-9]|2[0-9][0-9][0-9])[-](0?[1-9]|1[0-2])$'
321
             ],
322
            'nrinscestabprest' => [
323
                'required' => true,
324
                'type' => 'string',
325
                'regex' => '^[0-9]{11,14}$'
326
            ],
327
            'tpinsctomador' => [
328
                'required' => true,
329
                'type' => 'integer',
330
                'min' => 1,
331
                'max' => 4
332
            ],
333
            'nrinsctomador' => [
334
                'required' => true,
335
                'type' => 'string',
336
                'regex' => '^[0-9]{11,14}$'
337
            ],
338
        ];
339
        $this->validInputParameters($properties, $std);
340
341
        $this->method = "ConsultaReciboEvento{$evt}";
342
        $this->action = "{$this->namespace}ConsultasReinf/{$this->method}";
343
        $request = "<sped:{$this->method}>"
344
            . "<sped:tipoEvento>{$evt}</sped:tipoEvento>"
345
            . "<sped:tpInsc>{$this->tpInsc}</sped:tpInsc>"
346
            . "<sped:nrInsc>{$this->nrInsc}</sped:nrInsc>";
347
        if (!empty($std->perapur)) {
348
            $request .= "<sped:perApur>{$std->perapur}</sped:perApur>";
349
        }
350
        $request .= "<sped:nrInscEstabPrest>{$std->nrinscestabprest}</sped:nrInscEstabPrest>"
351
            . "<sped:tpInscTomador>{$std->tpinsctomador}</sped:tpInscTomador>"
352
            . "<sped:nrInscTomador>"
353
                . str_pad($std->nrinsctomador, 14, '0', STR_PAD_LEFT)
354
                . "</sped:nrInscTomador>"
355
            . "</sped:{$this->method}>";
356
        return $request;
357
    }
358
359
    /**
360
     * Consultation R2030, R2040, R2050
361
     * @param integer $evt
362
     * @param stdClass $std
363
     * @return string
364
     */
365
    protected function consultR20($evt, $std)
366
    {
367
        $properties = [
368
            'perapur' => [
369
                'required' => false,
370
                'type' => ['string',"null"],
371
                'regex' => '^(19[0-9][0-9]|2[0-9][0-9][0-9])[-](0?[1-9]|1[0-2])$'
372
            ],
373
            'nrinscestab' => [
374
                'required' => true,
375
                'type' => 'string',
376
                'regex' => '^[0-9]{11,14}$'
377
            ],
378
        ];
379
        $this->validInputParameters($properties, $std);
380
        if ($this->tpInsc !== 1) {
381
            throw new \InvalidArgumentException(
382
                "Somente com CNPJ essa consulta pode ser realizada."
383
                . " Seu config indica um CPF."
384
            );
385
        }
386
        $this->method = "ConsultaReciboEvento{$evt}";
387
        $this->action = "{$this->namespace}ConsultasReinf/{$this->method}";
388
        $request = "<sped:{$this->method}>"
389
            . "<sped:tipoEvento>{$evt}</sped:tipoEvento>"
390
            . "<sped:tpInsc>{$this->tpInsc}</sped:tpInsc>"
391
            . "<sped:nrInsc>{$this->nrInsc}</sped:nrInsc>";
392
        if (!empty($std->perapur)) {
393
            $request .= "<sped:perApur>{$std->perapur}</sped:perApur>";
394
        }
395
        $request .= "<sped:nrInscEstab>"
396
                . str_pad($std->nrinscestab, 14, '0', STR_PAD_LEFT)
397
                . "</sped:nrInscEstab>"
398
            . "</sped:{$this->method}>";
399
        return $request;
400
    }
401
    
402
    /**
403
     * Consultation R2055
404
     * @param integer $evt
405
     * @param stdClass $std
406
     * @return string
407
     */
408
    protected function consultR2055($evt, $std)
409
    {
410
        $properties = [
411
            'perapur' => [
412
                'required' => false,
413
                'type' => ['string',"null"],
414
                'regex' => '^(19[0-9][0-9]|2[0-9][0-9][0-9])[-](0?[1-9]|1[0-2])$'
415
            ],
416
            'nrinscestab' => [
417
                'required' => true,
418
                'type' => 'string',
419
                'regex' => '^[0-9]{11,14}$'
420
            ],
421
        ];
422
        $this->validInputParameters($properties, $std);
423
        if ($this->tpInsc !== 1) {
424
            throw new \InvalidArgumentException(
425
                "Somente com CNPJ essa consulta pode ser realizada."
426
                . " Seu config indica um CPF."
427
            );
428
        }
429
        $this->method = "ConsultaReciboEvento{$evt}";
430
        $this->action = "{$this->namespace}ConsultasReinf/{$this->method}";
431
        $request = "<sped:{$this->method}>"
432
            . "<sped:tipoEvento>{$evt}</sped:tipoEvento>"
433
            . "<sped:tpInsc>{$this->tpInsc}</sped:tpInsc>"
434
            . "<sped:nrInsc>{$this->nrInsc}</sped:nrInsc>";
435
        if (!empty($std->perapur)) {
436
            $request .= "<sped:perApur>{$std->perapur}</sped:perApur>";
437
        }
438
        $request .= "<sped:tpInscAdq>{$std->tpInscAdq}</sped:tpInscAdq>"
439
            . "<sped:nrInscAdq>{$std->nrInscAdq}</sped:nrInscAdq>"
440
            . "<sped:tpInscProd>{$std->tpInscProd}</sped:tpInscProd>"
441
            . "<sped:nrInscProd>{$std->nrInscProd}</sped:nrInscProd>"
442
            . "</sped:{$this->method}>";
443
        return $request;
444
    }
445
446
447
    /**
448
     * Consultation R2060
449
     * @param integer $evt
450
     * @param stdClass $std
451
     * @return string
452
     */
453
    protected function consultR2060($evt, $std)
454
    {
455
        $properties = [
456
            'perapur' => [
457
                'required' => false,
458
                'type' => ['string',"null"],
459
                'regex' => '^(19[0-9][0-9]|2[0-9][0-9][0-9])[-](0?[1-9]|1[0-2])$'
460
            ],
461
            'nrinscestabprest' => [
462
                'required' => true,
463
                'type' => 'string',
464
                'regex' => '^[0-9]{11,14}$'
465
            ],
466
            'tpinscestab' => [
467
                'required' => true,
468
                'type' => 'integer',
469
                'min' => 1,
470
                'max' => 2
471
            ],
472
            'nrinscestab' => [
473
                'required' => true,
474
                'type' => 'string',
475
                'regex' => '^[0-9]{11,14}$'
476
            ],
477
        ];
478
        $this->validInputParameters($properties, $std);
479
480
        $this->method = "ConsultaReciboEvento{$evt}";
481
        $this->action = "{$this->namespace}ConsultasReinf/{$this->method}";
482
        $request = "<sped:{$this->method}>"
483
            . "<sped:tipoEvento>{$evt}</sped:tipoEvento>"
484
            . "<sped:tpInsc>{$this->tpInsc}</sped:tpInsc>"
485
            . "<sped:nrInsc>{$this->nrInsc}</sped:nrInsc>";
486
        if (!empty($std->perapur)) {
487
            $request .= "<sped:perApur>{$std->perapur}</sped:perApur>";
488
        }
489
        $request .= "<sped:tpInscEstab>{$std->tpinscestab}</sped:tpInscEstab>"
490
            . "<sped:nrInscEstab>"
491
                . str_pad($std->nrinscestab, 14, '0', STR_PAD_LEFT)
492
                . "</sped:nrInscEstab>"
493
            . "</sped:{$this->method}>";
494
        return $request;
495
    }
496
497
    /**
498
     * Consultation R2098 and R2099
499
     * @param integer $evt
500
     * @param stdClass $std
501
     * @return string
502
     */
503
    protected function consultR209($evt, $std)
504
    {
505
        $properties = [
506
            'perapur' => [
507
                'required' => false,
508
                'type' => ['string',"null"],
509
                'regex' => '^(19[0-9][0-9]|2[0-9][0-9][0-9])[-](0?[1-9]|1[0-2])$'
510
            ],
511
        ];
512
        $this->validInputParameters($properties, $std);
513
514
        $this->method = "ConsultaReciboEvento{$evt}";
515
        $this->action = "{$this->namespace}ConsultasReinf/{$this->method}";
516
        $request = "<sped:{$this->method}>"
517
            . "<sped:tipoEvento>{$evt}</sped:tipoEvento>"
518
            . "<sped:tpInsc>{$this->tpInsc}</sped:tpInsc>"
519
            . "<sped:nrInsc>{$this->nrInsc}</sped:nrInsc>";
520
        if (!empty($std->perapur)) {
521
            $request .= "<sped:perApur>{$std->perapur}</sped:perApur>";
522
        }
523
        $request .= "</sped:{$this->method}>";
524
        return $request;
525
    }
526
527
    /**
528
     * Consultation R3010
529
     * @param integer $evt
530
     * @param stdClass $std
531
     * @return string
532
     */
533
    protected function consultR3010($evt, $std)
534
    {
535
        $properties = [
536
            'dtapur' => [
537
                'required' => true,
538
                'type' => 'string',
539
                'regex' => '^(19[0-9][0-9]|2[0-9][0-9][0-9])[-](0?[1-9]|1[0-2])[-](0?[1-9]|[1-2][0-9]|3[0-1])$'
540
            ],
541
            'nrinscestabelecimento' => [
542
                'required' => true,
543
                'type' => 'string',
544
                'regex' => '^[0-9]{11,14}$'
545
            ],
546
        ];
547
        $this->validInputParameters($properties, $std);
548
        if ($this->tpInsc !== 1) {
549
            throw new \InvalidArgumentException(
550
                "Somente com CNPJ essa consulta pode ser realizada."
551
                . " Seu config indica um CPF."
552
            );
553
        }
554
        $this->method = "ConsultaReciboEvento{$evt}";
555
        $this->action = "{$this->namespace}ConsultasReinf/{$this->method}";
556
        $request = "<sped:{$this->method}>"
557
            . "<sped:tipoEvento>{$evt}</sped:tipoEvento>"
558
            . "<sped:tpInsc>{$this->tpInsc}</sped:tpInsc>"
559
            . "<sped:nrInsc>{$this->nrInsc}</sped:nrInsc>"
560
            . "<sped:dtApur>{$std->dtapur}</sped:dtApur>"
561
            . "<sped:nrInscEstabelecimento>"
562
                . str_pad($std->nrinscestabelecimento, 14, '0', STR_PAD_LEFT)
563
                . "</sped:nrInscEstabelecimento>"
564
            . "</sped:{$this->method}>";
565
        return $request;
566
    }
567
568
    /**
569
     * Send batch of events
570
     * @param  integer $grupo
571
     * @param array $eventos
572
     * @return string
573
     */
574
    public function enviarLoteEventos($grupo, $eventos = [])
575
    {
576
        if (empty($eventos)) {
577
            return '';
578
        }
579
        //check number of events
580
        $nEvt = count($eventos);
581
        if ($nEvt > 100) {
582
            throw ProcessException::wrongArgument(2000, $nEvt);
583
        }
584
        $this->method = "ReceberLoteEventos";
585
        $this->action = "{$this->namespace}RecepcaoLoteReinf/{$this->method}";
586
        $xml = "";
587
        foreach ($eventos as $evt) {
588
            if (!is_a($evt, '\NFePHP\EFDReinf\Common\FactoryInterface')) {
589
                throw ProcessException::wrongArgument(2002, '');
590
            }
591
            //verifica se o evento pertence ao grupo indicado
592
            if (! in_array($evt->alias(), $this->grupos[$grupo])) {
593
                throw new \RuntimeException(
594
                    'O evento ' . $evt->alias() . ' não pertence a este grupo [ '
595
                    . $this->eventGroup[$grupo] . ' ].'
596
                );
597
            }
598
            $this->checkCertificate($evt);
599
            $xml .= "<evento id=\"".$evt->getId()."\">";
600
            $xml .= $evt->toXML();
601
            $xml .= "</evento>";
602
        }
603
        //build request
604
        $request = "<Reinf xmlns=\"http://www.reinf.esocial.gov.br/schemas/envioLoteEventos/v"
605
            . $this->serviceVersion."\" >"
606
            . "<loteEventos>"
607
            . $xml
608
            . "</loteEventos>"
609
            . "</Reinf>";
610
        //validate requisition with XSD
611
        $xsd = $this->path
612
            . "schemes/comunicacao/v$this->serviceVersion/"
613
            . $this->serviceXsd['EnvioLoteEventos']['name'];
614
        Validator::isValid($request, $xsd);
615
        //build soap body
616
        $body = "<sped:ReceberLoteEventos>"
617
            . "<sped:loteEventos>"
618
            . $request
619
            . "</sped:loteEventos>"
620
            . "</sped:ReceberLoteEventos>";
621
        $this->lastResponse = $this->sendRequest($body);
622
        return $this->lastResponse;
623
    }
624
625
    /**
626
     * Send request to webservice
627
     * @param string $request
628
     * @return string
629
     */
630
    protected function sendRequest($request)
631
    {
632
        if (empty($this->soap)) {
633
            $this->soap = new SoapCurl($this->certificate);
634
        }
635
        $envelope = "<soapenv:Envelope ";
636
        foreach ($this->soapnamespaces as $key => $xmlns) {
637
            $envelope .= "$key = \"$xmlns\" ";
638
        }
639
        $envelope .= ">"
640
            . "<soapenv:Header/>"
641
            . "<soapenv:Body>"
642
            . $request
643
            . "</soapenv:Body>"
644
            . "</soapenv:Envelope>";
645
646
        $msgSize = strlen($envelope);
647
        $parameters = [
648
            "Content-Type: text/xml;charset=UTF-8",
649
            "SOAPAction: \"$this->action\"",
650
            "Content-length: $msgSize"
651
        ];
652
        if ($this->method == 'ReceberLoteEventos') {
653
            $url = $this->uri[$this->tpAmb];
654
        } else {
655
            $url = $this->uriconsulta[$this->tpAmb];
656
        }
657
        $this->lastRequest = $envelope;
658
        return (string) $this->soap->send(
659
            $this->method,
660
            $url,
661
            $this->action,
662
            $envelope,
663
            $parameters
664
        );
665
    }
666
667
    /**
668
     * Verify the availability of a digital certificate.
669
     * If available, place it where it is needed
670
     * @param FactoryInterface $evento
671
     * @throws RuntimeException
672
     */
673
    protected function checkCertificate(FactoryInterface $evento)
674
    {
675
        //try to get certificate from event
676
        $certificate = $evento->getCertificate();
677
        if (empty($certificate)) {
678
            $evento->setCertificate($this->certificate);
679
        }
680
    }
681
682
    protected function validInputParameters($properties, $std)
683
    {
684
        foreach ($properties as $key => $rules) {
685
            $r = json_decode(json_encode($rules));
686
            if ($r->required) {
687
                if (!isset($std->$key)) {
688
                    throw new \Exception("$key não foi passado como parâmetro e é obrigatório.");
689
                }
690
                $value = $std->$key;
691
                if ($r->type === 'integer') {
692
                    if ($value < $r->min || $value > $r->max) {
693
                        throw new \Exception("$key contêm um valor invalido [$value].");
694
                    }
695
                }
696
                if ($r->type === 'string') {
697
                    if (!preg_match("/{$r->regex}/", $value)) {
698
                        throw new \Exception("$key contêm um valor invalido [$value].");
699
                    }
700
                }
701
            }
702
        }
703
    }
704
}
705