/** * anfavea * Função para transformar o campo cdata do padrão ANFAVEA para * texto imprimível * @param string $cdata campo CDATA * @return string conteúdo do campo CDATA como string */ private function pAnfavea($cdata = '') { if ($cdata == '') { return ''; } return $cdata; //remove qualquer texto antes ou depois da tag CDATA $cdata = str_replace('<![CDATA[', '<CDATA>', $cdata); $cdata = str_replace(']]>', '</CDATA>', $cdata); $cdata = preg_replace('/\\s\\s+/', ' ', $cdata); $cdata = str_replace("> <", "><", $cdata); $len = strlen($cdata); $startPos = strpos($cdata, '<'); if ($startPos === false) { return $cdata; } for ($x = $len; $x > 0; $x--) { if (substr($cdata, $x, 1) == '>') { $endPos = $x; break; } } if ($startPos > 0) { $parte1 = substr($cdata, 0, $startPos); } else { $parte1 = ''; } $parte2 = substr($cdata, $startPos, $endPos - $startPos + 1); if ($endPos < $len) { $parte3 = substr($cdata, $endPos + 1, $len - $endPos - 1); } else { $parte3 = ''; } $texto = trim($parte1) . ' ' . trim($parte3); if (strpos($parte2, '<CDATA>') === false) { $cdata = '<CDATA>' . $parte2 . '</CDATA>'; } else { $cdata = $parte2; } //carrega o xml CDATA em um objeto DOM $dom = new DomDocumentNFePHP(); $dom->loadXML($cdata, LIBXML_NOBLANKS | LIBXML_NOEMPTYTAG); //$xml = $dom->saveXML(); //grupo CDATA infADprod $id = $dom->getElementsByTagName('id')->item(0); $div = $dom->getElementsByTagName('div')->item(0); $entg = $dom->getElementsByTagName('entg')->item(0); $dest = $dom->getElementsByTagName('dest')->item(0); $ctl = $dom->getElementsByTagName('ctl')->item(0); $ref = $dom->getElementsByTagName('ref')->item(0); if (isset($id)) { if ($id->hasAttributes()) { foreach ($id->attributes as $attr) { $name = $attr->nodeName; $value = $attr->nodeValue; $texto .= " {$name} : {$value}"; } } } if (isset($div)) { if ($div->hasAttributes()) { foreach ($div->attributes as $attr) { $name = $attr->nodeName; $value = $attr->nodeValue; $texto .= " {$name} : {$value}"; } } } if (isset($entg)) { if ($entg->hasAttributes()) { foreach ($entg->attributes as $attr) { $name = $attr->nodeName; $value = $attr->nodeValue; $texto .= " {$name} : {$value}"; } } } if (isset($dest)) { if ($dest->hasAttributes()) { foreach ($dest->attributes as $attr) { $name = $attr->nodeName; $value = $attr->nodeValue; $texto .= " {$name} : {$value}"; } } } if (isset($ctl)) { if ($ctl->hasAttributes()) { foreach ($ctl->attributes as $attr) { $name = $attr->nodeName; $value = $attr->nodeValue; $texto .= " {$name} : {$value}"; } } } if (isset($ref)) { if ($ref->hasAttributes()) { foreach ($ref->attributes as $attr) { $name = $attr->nodeName; $value = $attr->nodeValue; $texto .= " {$name} : {$value}"; } } } //grupo CADATA infCpl $t = $dom->getElementsByTagName('transmissor')->item(0); $r = $dom->getElementsByTagName('receptor')->item(0); $versao = !empty($dom->getElementsByTagName('versao')->item(0)->nodeValue) ? 'Versao:' . $dom->getElementsByTagName('versao')->item(0)->nodeValue . ' ' : ''; $especieNF = !empty($dom->getElementsByTagName('especieNF')->item(0)->nodeValue) ? 'Especie:' . $dom->getElementsByTagName('especieNF')->item(0)->nodeValue . ' ' : ''; $fabEntrega = !empty($dom->getElementsByTagName('fabEntrega')->item(0)->nodeValue) ? 'Entrega:' . $dom->getElementsByTagName('fabEntrega')->item(0)->nodeValue . ' ' : ''; $dca = !empty($dom->getElementsByTagName('dca')->item(0)->nodeValue) ? 'dca:' . $dom->getElementsByTagName('dca')->item(0)->nodeValue . ' ' : ''; $texto .= "" . $versao . $especieNF . $fabEntrega . $dca; if (isset($t)) { if ($t->hasAttributes()) { $texto .= " Transmissor "; foreach ($t->attributes as $attr) { $name = $attr->nodeName; $value = $attr->nodeValue; $texto .= " {$name} : {$value}"; } } } if (isset($r)) { if ($r->hasAttributes()) { $texto .= " Receptor "; foreach ($r->attributes as $attr) { $name = $attr->nodeName; $value = $attr->nodeValue; $texto .= " {$name} : {$value}"; } } } return $texto; }
/** * autoriza * Envia NFe para a SEFAZ autorizar. * ATENÇÃO! Este é o antigo método "sendLot()" que enviava lotes de NF-e versão "2.00" * consumindo o WS "NfeRecepcao2", agora este método está preparado apenas para a versão * "3.10" e por isso utiliza o WS "NfeAutorizacao" sempre em modo síncrono. * * @name autoriza * @package NFePHP * @author Roberto L. Machado <linux.rlm at gmail dot com> * @param string $sxml string com uma nota fiscal em xml * @param integer $idLote id do lote e um numero (numeração sequencial) * @param array $aRetorno parametro passado por referencia contendo a resposta da consulta em um array * @param integer $indSinc Indicação webservice assíncrono (0) ou síncrono (1) * @return mixed string XML do retorno do webservice, ou false se ocorreu algum erro */ public function autoriza($sxml, $idLote, &$aRetorno = array(), $indSinc = 0) { try { //retorno do método em array (esta estrutura espelha a estrutura do XML retornado pelo webservice //IMPORTANTE: esta estrutura varia parcialmente conforme o $indSinc $aRetorno = array( 'bStat'=>false, 'tpAmb'=>'', 'verAplic'=>'', 'cStat'=>'', 'xMotivo'=>'', 'cUF'=>'', 'dhRecbto'=>''); if ($indSinc === 0) { //dados do recibo do lote (gerado apenas se o lote for aceito) $aRetorno['infRec'] = array('nRec'=>'','tMed'=>''); } elseif ($indSinc === 1) { //dados do protocolo de recebimento da NF-e $aRetorno['protNFe'] = array( 'versao'=>'', 'infProt'=>array( //informações do protocolo de autorização da NF-e 'tpAmb'=>'', 'verAplic'=>'', 'chNFe'=>'', 'dhRecbto'=>'', 'nProt'=>'', 'digVal'=>'', 'cStat'=>'', 'xMotivo'=>'')); } else { throw new nfephpException("Parametro indSinc deve ser inteiro 0 ou 1, verifique!!"); } //verifica se alguma SVC esta habilitada, neste caso precisa recarregar os webservices if ($this->enableSVCAN) { $aURL = $this->pLoadSEFAZ($this->tpAmb, self::CONTINGENCIA_SVCAN); } elseif ($this->enableSVCRS) { $aURL = $this->pLoadSEFAZ($this->tpAmb, self::CONTINGENCIA_SVCRS); } else { $aURL = $this->aURL; } //identificação do serviço: autorização de NF-e $servico = 'NfeAutorizacao'; //recuperação da versão $versao = $aURL[$servico]['version']; //recuperação da url do serviço $urlservico = $aURL[$servico]['URL']; //recuperação do método $metodo = $aURL[$servico]['method']; //montagem do namespace do serviço $operation = $aURL[$servico]['operation']; $namespace = $this->URLPortal.'/wsdl/'.$operation; //valida o parâmetro da string do XML da NF-e if (empty($sxml) || ! simplexml_load_string($sxml)) { throw new nfephpException("XML de NF-e para autorizacao " . "recebido no parametro parece invalido, verifique"); } // limpa a variavel $sNFe = $sxml; //remove <?xml version="1.0" encoding=... e demais caracteres indesejados $sNFe = preg_replace("/<\?xml.*\?>/", "", $sNFe); $sNFe = str_replace(array("\r","\n","\s"), "", $sNFe); //montagem do cabeçalho da comunicação SOAP $cabec = "<nfeCabecMsg xmlns=\"$namespace\">" . "<cUF>$this->cUF</cUF>" . "<versaoDados>$versao</versaoDados>" . "</nfeCabecMsg>"; //montagem dos dados da mensagem SOAP $dados = "<nfeDadosMsg xmlns=\"$namespace\">" . "<enviNFe xmlns=\"$this->URLPortal\" versao=\"$versao\">" . "<idLote>$idLote</idLote>" . "<indSinc>$indSinc</indSinc>$sNFe</enviNFe></nfeDadosMsg>"; //envia dados via SOAP $retorno = $this->pSendSOAP($urlservico, $namespace, $cabec, $dados, $metodo, $this->tpAmb); //verifica o retorno if (! $retorno) { throw new nfephpException("Nao houve retorno Soap verifique a mensagem de erro e o debug!!"); } //tratar dados de retorno $doc = new DomDocumentNFePHP(); $doc->loadXML($retorno, LIBXML_NOBLANKS | LIBXML_NOEMPTYTAG); $cStat = $this->pSimpleGetValue($doc, "cStat"); $xMotivo = $this->pSimpleGetValue($doc, "xMotivo"); //verifica o codigo do status da resposta, se vazio houve erro if ($cStat == '') { throw new nfephpException("O retorno nao contem cStat verifique o debug do soap !!"); } elseif ($indSinc === 0 && $cStat == '103') { //103-Lote recebido com sucesso $aRetorno['bStat'] = true; } elseif ($indSinc === 1 && $cStat == '104') { //104-Lote processado, podendo ter ou não o protNFe (#AR11 no layout) $aRetorno['bStat'] = true; } else { throw new nfephpException(sprintf("%s - %s", $cStat, $xMotivo)); } // status da resposta do webservice $aRetorno['cStat'] = $cStat; // motivo da resposta (opcional) $aRetorno['xMotivo'] = $this->pSimpleGetValue($doc, "xMotivo"); // data e hora da mensagem (opcional) if ($dhRecbto = $this->pSimpleGetValue($doc, "dhRecbto")) { $aRetorno['dhRecbto'] = date("d/m/Y H:i:s", $this->pConvertTime($dhRecbto)); } //tipo do ambiente, versão do aplicativo e código da UF $aRetorno['tpAmb'] = $this->pSimpleGetValue($doc, "tpAmb"); $aRetorno['verAplic'] = $this->pSimpleGetValue($doc, "verAplic"); $aRetorno['cUF'] = $this->pSimpleGetValue($doc, "cUF"); if ($indSinc == 1) { //retorno síncrono do webservice: dados do protocolo da NF-e $nodeProtNFe = $doc->getElementsByTagName('protNFe')->item(0); $nodeInfProt = $doc->getElementsByTagName('infProt')->item(0); $aRetorno['protNFe']['versao'] = $nodeProtNFe->getAttribute('versao'); $infProt = array(); $infProt['tpAmb'] = $this->pSimpleGetValue($nodeInfProt, "tpAmb"); $infProt['verAplic'] = $this->pSimpleGetValue($nodeInfProt, "verAplic"); $infProt['chNFe'] = $this->pSimpleGetValue($nodeInfProt, "chNFe"); $dhRecbto = $this->pSimpleGetValue($nodeInfProt, "dhRecbto"); $infProt['dhRecbto'] = date("d/m/Y H:i:s", $this->pConvertTime($dhRecbto)); $infProt['digVal'] = $this->pSimpleGetValue($nodeInfProt, "digVal"); $infProt['cStat'] = $this->pSimpleGetValue($nodeInfProt, "cStat"); $infProt['xMotivo'] = $this->pSimpleGetValue($nodeInfProt, "xMotivo"); //número do protocolo de autorização (opcional) $infProt['nProt'] = $this->pSimpleGetValue($nodeInfProt, "nProt"); $aRetorno['protNFe']['infProt'] = $infProt; //nome do arquivo de retorno: chave da NF-e com sufixo "-prot" $nome = $this->temDir.$infProt['chNFe'].'-prot.xml'; } else { //retorno assíncrono do webservice: dados do recibo do lote $aRetorno['infRec'] = array(); $aRetorno['infRec']['nRec'] = $this->pSimpleGetValue($doc, "nRec"); $aRetorno['infRec']['tMed'] = $this->pSimpleGetValue($doc, "tMed"); //nome do arquivo de retorno: ID do lote com sufixo "-prot" $nome = $this->temDir.$idLote.'-rec.xml'; } //grava o retorno na pasta de temporários $nome = $doc->save($nome); } catch (nfephpException $e) { $this->pSetError($e->getMessage()); if ($this->exceptions) { throw $e; } return false; } return $retorno; }// fim autoriza