Completed
Push — master ( 20633e...cfc7c7 )
by Roberto
07:37 queued 04:42
created

Tools::consultarLoteEventos()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 38
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 38
ccs 0
cts 37
cp 0
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 33
nc 1
nop 1
crap 2
1
<?php
2
3
namespace NFePHP\eSocial;
4
5
/**
6
 * Classe Tools, performs communication with the e-Social webservice
7
 *
8
 * @category  NFePHP
9
 * @package   NFePHP\eSocial\Tools
10
 * @copyright Copyright (c) 2017
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-esocial for the canonical source repository
16
 */
17
use InvalidArgumentException;
18
use NFePHP\Common\Certificate;
19
use NFePHP\Common\Validator;
20
use NFePHP\eSocial\Common\FactoryInterface;
21
use NFePHP\eSocial\Common\Soap\SoapCurl;
22
use NFePHP\eSocial\Common\Soap\SoapInterface;
23
use NFePHP\eSocial\Common\Tools as ToolsBase;
24
use RuntimeException;
25
26
class Tools extends ToolsBase
27
{
28
    /**
29
     * @var string
30
     */
31
    public $lastRequest;
32
    /**
33
     * @var string
34
     */
35
    public $lastResponse;
36
    /**
37
     * @var \NFePHP\Common\Soap\SoapInterface
38
     */
39
    protected $soap;
40
    /**
41
     * @var array
42
     */
43
    protected $soapnamespaces = [
44
        'xmlns:xsi'  => "http://www.w3.org/2001/XMLSchema-instance",
45
        'xmlns:xsd'  => "http://www.w3.org/2001/XMLSchema",
46
        'xmlns:soap' => "http://www.w3.org/2003/05/soap-envelope",
47
    ];
48
    /**
49
     * @var \SOAPHeader
50
     */
51
    protected $objHeader;
52
    /**
53
     * @var string
54
     */
55
    protected $xmlns;
56
    /**
57
     * @var string
58
     */
59
    protected $uri;
60
    /**
61
     * @var string
62
     */
63
    protected $action;
64
    /**
65
     * @var string
66
     */
67
    protected $method;
68
    /**
69
     * @var array
70
     */
71
    protected $parameters;
72
    /**
73
     * @var string
74
     */
75
    protected $envelopeXmlns;
76
    
77
    /**
78
     * Constructor
79
     * @param string $config
80
     * @param Certificate $certificate
81
     */
82
    public function __construct($config, Certificate $certificate)
83
    {
84
        parent::__construct($config, $certificate);
85
    }
86
87
    /**
88
     * SOAP communication dependency injection
89
     * @param SoapInterface $soap
90
     */
91
    public function loadSoapClass(SoapInterface $soap)
92
    {
93
        $this->soap = $soap;
0 ignored issues
show
Documentation Bug introduced by
It seems like $soap of type object<NFePHP\eSocial\Common\Soap\SoapInterface> is incompatible with the declared type object<NFePHP\Common\Soap\SoapInterface> of property $soap.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
94
    }
95
96
    /**
97
     * Event batch query
98
     * @param  string $protocolo
99
     * @return string
100
     */
101
    public function consultarLoteEventos($protocolo)
102
    {
103
        $operationVersion = $this->serviceXsd['ConsultaLoteEventos']['version'];
104
        $this->action = "http://www.esocial.gov.br/servicos/empregador/lote"
105
            ."/eventos/envio/consulta/retornoProcessamento/$operationVersion"
106
            ."/ServicoConsultarLoteEventos/ConsultarLoteEventos";
107
        $this->method = "ConsultarLoteEventos";
108
        $this->uri = "https://webservices.producaorestrita.esocial.gov.br"
109
            ."/servicos/empregador/consultarloteeventos"
110
            ."/WsConsultarLoteEventos.svc";
111
        $this->envelopeXmlns = [
0 ignored issues
show
Documentation Bug introduced by
It seems like array('xmlns:soapenv' =>...o/{$operationVersion}") of type array<string,string,{"xm...","xmlns:v1":"string"}> is incompatible with the declared type string of property $envelopeXmlns.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
112
            'xmlns:soapenv' => "http://schemas.xmlsoap.org/soap/envelope/",
113
            'xmlns:v1'      => "http://www.esocial.gov.br/servicos/empregador/lote"
114
                ."/eventos/envio/consulta/retornoProcessamento/$operationVersion",
115
        ];
116
        $request = "<eSocial xmlns=\"http://www.esocial.gov.br/schema/lote"
117
            ."/eventos/envio/consulta/retornoProcessamento/v1_0_0\" "
118
            ."xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
119
            ."<consultaLoteEventos>"
120
            ."<protocoloEnvio>$protocolo</protocoloEnvio>"
121
            ."</consultaLoteEventos>"
122
            ."</eSocial>";
123
        //validar a requisição conforme o seu respectivo XSD
124
        Validator::isValid(
125
            $request,
126
            $this->path
127
            ."schemes/comunicacao/$this->serviceStr/"
128
            ."ConsultaLoteEventos-$operationVersion.xsd"
129
        );
130
        $body = "<v1:ConsultarLoteEventos>"
131
            ."<v1:consulta>"
132
            .$request
133
            ."</v1:consulta>"
134
            ."</v1:ConsultarLoteEventos>";
135
        $this->lastRequest  = $body;
136
        $this->lastResponse = $this->sendRequest($body);
137
        return $this->lastResponse;
138
    }
139
140
    /**
141
     * Send request to webservice
142
     * @param  string $request
143
     * @return string
144
     */
145
    protected function sendRequest($request)
146
    {
147
        if (empty($this->soap)) {
148
            $this->soap = new SoapCurl($this->certificate);
0 ignored issues
show
Documentation Bug introduced by
It seems like new \NFePHP\eSocial\Comm...url($this->certificate) of type object<NFePHP\eSocial\Common\Soap\SoapCurl> is incompatible with the declared type object<NFePHP\Common\Soap\SoapInterface> of property $soap.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
149
        }
150
        $envelope = "<soapenv:Envelope ";
151
        foreach ($this->envelopeXmlns as $key => $xmlns) {
0 ignored issues
show
Bug introduced by
The expression $this->envelopeXmlns of type string is not traversable.
Loading history...
152
            $envelope .= "$key = \"$xmlns\" ";
153
        }
154
        $envelope .= ">"
155
            ."<soapenv:Header/>"
156
            ."<soapenv:Body>"
157
            .$request
158
            ."</soapenv:Body>"
159
            ."</soapenv:Envelope>";
160
        $msgSize    = strlen($envelope);
161
        $parameters = [
162
            "Content-Type: text/xml;charset=UTF-8",
163
            "SOAPAction: \"$this->action\"",
164
            "Content-length: $msgSize",
165
        ];
166
        //return $envelope;
167
        return (string) $this->soap->send(
168
            $this->method,
169
            $this->uri,
170
            $this->action,
171
            $envelope,
172
            $parameters
173
        );
174
    }
175
176
    /**
177
     * Send batch of events
178
     * @param  integer $grupo
179
     * @param  array $eventos
180
     * @return string
181
     */
182
    public function enviarLoteEventos($grupo, $eventos = [])
183
    {
184
        if (empty($eventos)) {
185
            return '';
186
        }
187
        $xml  = "";
188
        $nEvt = count($eventos);
189
        if ($nEvt > 50) {
190
            throw new InvalidArgumentException(
191
                "O numero máximo de eventos em um lote é 50, "
192
                ."você está tentando enviar $nEvt eventos !"
193
            );
194
        }
195
        foreach ($eventos as $evt) {
196
            //verifica se o evento pertence ao grupo indicado
197
            if (! in_array($evt->alias(), $this->grupos[$grupo])) {
198
                throw new RuntimeException(
199
                    'O evento ' . $evt->alias() . ' não pertence a este grupo [ '
200
                    . $this->eventGroup[$grupo] . ' ].'
201
                );
202
            }
203
            $this->checkCertificate($evt);
204
            $xml .= "<evento Id=\"$evt->evtid\">";
205
            $xml .= $evt->toXML();
206
            $xml .= "</evento>";
207
        }
208
        $operationVersion = $this->serviceXsd['EnvioLoteEventos']['version'];
209
        $this->method = "EnviarLoteEventos";
210
        $this->action = "http://www.esocial.gov.br/servicos/empregador/lote"
211
            . "/eventos/envio/v1_1_0/ServicoEnviarLoteEventos"
212
            . "/EnviarLoteEventos";
213
        $this->uri = "https://webservices.producaorestrita.esocial.gov.br"
214
            ."/servicos/empregador/enviarloteeventos/WsEnviarLoteEventos.svc";
215
        $this->envelopeXmlns = [
0 ignored issues
show
Documentation Bug introduced by
It seems like array('xmlns:soapenv' =>...o/{$operationVersion}") of type array<string,string,{"xm...","xmlns:v1":"string"}> is incompatible with the declared type string of property $envelopeXmlns.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
216
            'xmlns:soapenv' => "http://schemas.xmlsoap.org/soap/envelope/",
217
            'xmlns:v1'      => "http://www.esocial.gov.br/servicos/empregador"
218
                . "/lote/eventos/envio/$operationVersion",
219
        ];
220
        $request = "<eSocial xmlns=\"http://www.esocial.gov.br/schema/lote"
221
            . "/eventos/envio/$operationVersion\" "
222
            . "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
223
            . "<envioLoteEventos grupo=\"$grupo\">"
224
            . "<ideEmpregador>"
225
            . "<tpInsc>$this->tpInsc</tpInsc>"
226
            . "<nrInsc>$this->nrInsc</nrInsc>"
227
            . "</ideEmpregador>"
228
            . "<ideTransmissor>"
229
            . "<tpInsc>$this->transmissortpInsc</tpInsc>"
230
            . "<nrInsc>$this->transmissornrInsc</nrInsc>"
231
            . "</ideTransmissor>"
232
            . "<eventos>"
233
            . "$xml"
234
            . "</eventos>"
235
            . "</envioLoteEventos>"
236
            . "</eSocial>";
237
        //validar a requisição conforme o seu respectivo XSD
238
        Validator::isValid(
239
            $request,
240
            $this->path
241
            . "schemes/comunicacao/$this->serviceStr/"
242
            . "EnvioLoteEventos-$operationVersion.xsd"
243
        );
244
        $body = "<v1:EnviarLoteEventos>"
245
            . "<v1:loteEventos>"
246
            . $request
247
            . "</v1:loteEventos>"
248
            . "</v1:EnviarLoteEventos>";
249
        $this->lastRequest  = $body;
250
        $this->lastResponse = $this->sendRequest($body);
251
        return $this->lastResponse;
252
    }
253
254
    /**
255
     * Verify the availability of a digital certificate.
256
     * If available, place it where it is needed
257
     * @param  FactoryInterface $evento
258
     * @throws RuntimeException
259
     */
260
    protected function checkCertificate(FactoryInterface $evento)
261
    {
262
        if (empty($this->certificate)) {
263
            //try to get certificate from event
264
            $certificate = $evento->getCertificate();
265
            if (empty($certificate)) {
266
                //oops no certificate avaiable
267
                throw new \RuntimeException("Não temos um certificado disponível!");
268
            }
269
            $this->certificate = $certificate;
270
        } else {
271
            $certificate = $evento->getCertificate();
272
            if (empty($certificate)) {
273
                $evento->setCertificate($this->certificate);
274
            }
275
        }
276
    }
277
}
278