/** * 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; }
/** * manifDest * Manifestação do detinatário NT2012-002. * 210200 – Confirmação da Operação * 210210 – Ciência da Operação * 210220 – Desconhecimento da Operação * 210240 – Operação não Realizada * * @name manifDest * @param string $chNFe Chave da NFe * @param string $tpEvento Tipo do evento pode conter 2 ou 6 digitos ex. 00 ou 210200 * @param string $xJust Justificativa quando tpEvento = 40 ou 210240 * @param integer $tpAmb Tipo de ambiente * @param mixed $resp variável passada como referencia e irá conter o retorno da função em um array * @return false ou xml do retorno do webservice */ public function manifDest($chNFe = '', $tpEvento = '', $xJust = '', $tpAmb = '', &$resp = array()) { try { if ($chNFe == '') { $msg = "A chave da NFe recebida é obrigatória."; throw new nfephpException($msg); } if ($tpEvento == '') { $msg = "O tipo de evento não pode ser vazio."; throw new nfephpException($msg); } if (strlen($tpEvento) == 2) { $tpEvento = "2102$tpEvento"; } if (strlen($tpEvento) != 6) { $msg = "O comprimento do código do tipo de evento está errado."; throw new nfephpException($msg); } switch ($tpEvento) { case '210200': $descEvento = 'Confirmacao da Operacao'; //confirma a operação e o recebimento da mercadoria (para as operações //com circulação de mercadoria) //Após a Confirmação da Operação pelo destinatário, a empresa emitente //fica automaticamente impedida de cancelar a NF-e break; case '210210': $descEvento = 'Ciencia da Operacao'; //encrenca !!! Não usar //O evento de “Ciência da Operação” é um evento opcional e pode ser evitado //Após um período determinado, todas as operações com “Ciência da Operação” deverão //obrigatoriamente ter a manifestação final do destinatário declarada em um dos eventos de //Confirmação da Operação, Desconhecimento ou Operação não Realizada break; case '210220': $descEvento = 'Desconhecimento da Operacao'; //Uma empresa pode ficar sabendo das operações destinadas a um determinado CNPJ //consultando o “Serviço de Consulta da Relação de Documentos Destinados” ao seu CNPJ. //O evento de “Desconhecimento da Operação” permite ao destinatário informar o seu //desconhecimento de uma determinada operação que conste nesta relação, por exemplo break; case '210240': $descEvento = 'Operacao nao Realizada'; //não aceitação no recebimento que antes se fazia com apenas um carimbo na NF //operação não foi realizada (com Recusa de Recebimento da mercadoria e outros motivos), //não cabendo neste caso a emissão de uma Nota Fiscal de devolução. break; default: $msg = "O código do tipo de evento informado não corresponde a " . "nenhum evento de manifestação de destinatário."; throw new nfephpException($msg); } $resp = array('bStat'=>false,'cStat'=>'','xMotivo'=>'','arquivo'=>''); if ($tpEvento == '210240' && $xJust == '') { $msg = "Uma Justificativa é obrigatória para o evento de Operação não Realizada."; throw new nfephpException($msg); } //limpa o texto de correção para evitar surpresas $xJust = $this->pCleanString($xJust); //ajusta ambiente if ($tpAmb == '') { $tpAmb = $this->tpAmb; } //utilizar AN para enviar o manifesto $sigla = 'AN'; $aURL = $this->pLoadSEFAZ($tpAmb, $sigla); $cOrgao='91'; $numLote = $this->pGeraNumLote(); //Data e hora do evento no formato AAAA-MM-DDTHH:MM:SSTZD (UTC) $dhEvento = date('Y-m-d').'T'.date('H:i:s').$this->timeZone; //montagem do namespace do serviço $servico = 'RecepcaoEvento'; //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; // 2 + 6 + 44 + 2 = 54 digitos //“ID” + tpEvento + chave da NF-e + nSeqEvento $nSeqEvento = '1'; $id = "ID".$tpEvento.$chNFe.'0'.$nSeqEvento; //monta mensagem $Ev=''; $Ev .= "<evento xmlns=\"$this->URLPortal\" versao=\"$versao\">"; $Ev .= "<infEvento Id=\"$id\">"; $Ev .= "<cOrgao>$cOrgao</cOrgao>"; $Ev .= "<tpAmb>$tpAmb</tpAmb>"; $Ev .= "<CNPJ>$this->cnpj</CNPJ>"; $Ev .= "<chNFe>$chNFe</chNFe>"; $Ev .= "<dhEvento>$dhEvento</dhEvento>"; $Ev .= "<tpEvento>$tpEvento</tpEvento>"; $Ev .= "<nSeqEvento>$nSeqEvento</nSeqEvento>"; $Ev .= "<verEvento>$versao</verEvento>"; $Ev .= "<detEvento versao=\"$versao\">"; $Ev .= "<descEvento>$descEvento</descEvento>"; if ($xJust != '') { $Ev .= "<xJust>$xJust</xJust>"; } $Ev .= "</detEvento></infEvento></evento>"; //assinatura dos dados $tagid = 'infEvento'; $Ev = $this->signXML($Ev, $tagid); $Ev = $this->pClearXml($Ev, true); //montagem dos dados $dados = ''; $dados .= "<envEvento xmlns=\"$this->URLPortal\" versao=\"$versao\">"; $dados .= "<idLote>$numLote</idLote>"; $dados .= $Ev; $dados .= "</envEvento>"; //montagem da mensagem $cabec = "<nfeCabecMsg xmlns=\"$namespace\"><cUF>$this->cUF</cUF>" . "<versaoDados>$versao</versaoDados></nfeCabecMsg>"; $dados = "<nfeDadosMsg xmlns=\"$namespace\">$dados</nfeDadosMsg>"; //grava solicitação em temp if (! file_put_contents($this->temDir."$chNFe-$nSeqEvento-envMDe.xml", $Ev)) { throw new nfephpException("Falha na gravacao do arquivo envMDe!!"); } //envia dados via SOAP e verifica o retorno, se nao houve gera excecao if (!$retorno = $this->pSendSOAP($urlservico, $namespace, $cabec, $dados, $metodo, $tpAmb)) { throw new nfephpException("Nao houve retorno Soap verifique a mensagem de erro e o debug!!"); } //tratar dados de retorno $xmlMDe = new DomDocumentNFePHP($retorno); $retEvento = $xmlMDe->getElementsByTagName("retEvento")->item(0); $infEvento = $xmlMDe->getElementsByTagName("infEvento")->item(0); $cStat = !empty($retEvento->getElementsByTagName('cStat')->item(0)->nodeValue) ? $retEvento->getElementsByTagName('cStat')->item(0)->nodeValue : ''; $xMotivo = !empty($retEvento->getElementsByTagName('xMotivo')->item(0)->nodeValue) ? $retEvento->getElementsByTagName('xMotivo')->item(0)->nodeValue : ''; if ($cStat == '') { //houve erro $msg = "cStat está em branco, houve erro na comunicação Soap " . "verifique a mensagem de erro e o debug!!"; throw new nfephpException($msg); } //tratar erro de versão do XML if ($cStat == '238' || $cStat == '239') { $this->pTrata239($retorno, $sigla, $tpAmb, $servico, $versao); $msg = "Versão do arquivo XML não suportada no webservice!!"; throw new nfephpException($msg); } //erro no processamento if ($cStat != '135' && $cStat != '136') { //se cStat <> 135 houve erro e o lote foi rejeitado $msg = "O Lote foi rejeitado : $cStat - $xMotivo\n"; throw new nfephpException($msg); } if ($cStat == '136') { $msg = "O Evento foi registrado mas a NFe não foi localizada : $cStat - $xMotivo\n"; throw new nfephpException($msg); } //o evento foi aceito $xmlenvMDe = new DomDocumentNFePHP($Ev); $evento = $xmlenvMDe->getElementsByTagName("evento")->item(0); //Processo completo solicitação + protocolo $xmlprocMDe = new DomDocumentNFePHP(); //cria a tag procEventoNFe $procEventoNFe = $xmlprocMDe->createElement('procEventoNFe'); $xmlprocMDe->appendChild($procEventoNFe); //estabele o atributo de versão $eventProc_att1 = $procEventoNFe->appendChild($xmlprocMDe->createAttribute('versao')); $eventProc_att1->appendChild($xmlprocMDe->createTextNode($versao)); //estabelece o atributo xmlns $eventProc_att2 = $procEventoNFe->appendChild($xmlprocMDe->createAttribute('xmlns')); $eventProc_att2->appendChild($xmlprocMDe->createTextNode($this->URLPortal)); //carrega o node evento $node1 = $xmlprocMDe->importNode($evento, true); $procEventoNFe->appendChild($node1); //carrega o node retEvento $node2 = $xmlprocMDe->importNode($retEvento, true); $procEventoNFe->appendChild($node2); //salva o xml como string em uma variável $procXML = $xmlprocMDe->saveXML(); //remove as informações indesejadas $procXML = $this->pClearXml($procXML, false); $filename = $this->evtDir."$chNFe-$tpEvento-$nSeqEvento-procMDe.xml"; $resp = array('bStat'=>true,'cStat'=>$cStat,'xMotivo'=>$xMotivo,'arquivo'=>$filename); //salva o arquivo xml if (!file_put_contents($filename, $procXML)) { $msg = "Falha na gravacao do arquivo procMDe!!"; throw new nfephpException($msg); } } catch (nfephpException $e) { $this->pSetError($e->getMessage()); if ($this->exceptions) { throw $e; } $resp = array('bStat'=>false,'cStat'=>$cStat,'xMotivo'=>$xMotivo,'arquivo'=>''); return false; } return $retorno; } //fim manifDest