O controle de contingencia deve ser usado quando o SEFAZ se torna instável, sem acesso ou a empresa está sem internet.
Durante uma urgência, a emissão da nota deve ser feita neste modelo contingenciada e no primeiro minuto do problema ter sido sanado transmitida para o portal.
Podemos fazer uso da função de checagem de status do sefaz mas muitos abusam e verificam muitas vezes por minuto o que acarreta consumo indevido.
O primeiro passo para se emitir notas em contingencia é verificar se tem internet ativa, caso não, emita.
Caso a internet esteja ativa, deve-se consultar o estado do portal e caso esteja fora do ar, caso esteja fora do ar, emita.
Para diminuir o uso da função de status e como o usuário está muito atarefado para abrir o browser, entrar no portal e verificar a situação dos servidores então pode-se programar para isto um monitor rústico.
Segue exemplo, usando Fivewin e conversação HTTP básica, leitura RAW da resposta, capturas de substrings, etc:
Código: Selecionar todos
FUNCTION SefazStatus( _bar_, lFazTeste )
/* rochinha - 10/08/2024 */
// aTDCols := { "Autorizador", "Autorizacao", "Retorno", "Inutilizacao", "ConsStatus", "Status", "TempoMedio", "ConsCadastro", "RecepEventos" }
// Function IEGetPage( URL, lFazTeste )
default lFazTeste := .f.
#translate _InternetExplorer() => /* win_ole */ CreateObject( "InternetExplorer.Application" )
#translate _MicrosoftXMLHTTP() => /* win_ole */ CreateObject( "Microsoft.XMLHTTP" )
#translate _MSXML2ServerXMLHTTP() => /* win_ole */ CreateObject( "MSXML2.ServerXMLHTTP" )
#translate _XMLHttpRequest() => /* win_ole */ CreateObject( "Microsoft.XMLHTTP" )
#translate _WinHttpRequest() => /* win_ole */ CreateObject( "WinHttp.WinHttpRequest.5.1" )
#translate _MicrosoftXMLDOM() => /* win_ole */ CreateObject( "Microsoft.XMLDOM" )
if VerifyINI( "SEFAZ", "VerificaStatus", "N", cPathDados+"\nfw.ini", .f. ) = "N"
RETURN nil
endif
cEanApi := "https://www.nfe.fazenda.gov.br/portal/disponibilidade.aspx"
//winexec( "taskkill /f /im iexplore.exe" ,0)
SysWait(5)
//oIE := _InternetExplorer()
//cHTMLdoc := HTMLDocument
cPathRaiz := cPathDados
if lFazTeste
cXMLSedex := []
cXMLSedex := cXMLSedex + [<html>]
cXMLSedex := cXMLSedex + [<table class="tabelaListagemDados" cellspacing="0" rules="all" border="1" id="ctl00_ContentPlaceHolder1_gdvDisponibilidade2">]
cXMLSedex := cXMLSedex + [ <caption>]
cXMLSedex := cXMLSedex + [ Visão Geral de Disponibilidade dos Serviços<br/><span class='fonte10'> - Última Verificação: 27/07/2024 18:29:28<br/><br/> - WebServices Versão 4.00</span>]
cXMLSedex := cXMLSedex + [ </caption><tr>]
cXMLSedex := cXMLSedex + [ <th scope="col">Autorizador</th><th scope="col">Autorização4</th><th scope="col">Retorno Autorização4</th><th scope="col">Inutilização4</th><th scope="col">Consulta Protocolo4</th><th scope="col">Status Serviço4</th><th scope="col">Tempo Médio</th><th scope="col">Consulta Cadastro4</th><th scope="col">Recepção Evento4</th>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaImparCentralizada">]
cXMLSedex := cXMLSedex + [ <td>AM</td> <td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><span></span></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaParCentralizada">]
cXMLSedex := cXMLSedex + [ <td>BA</td> <td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaImparCentralizada">]
cXMLSedex := cXMLSedex + [ <td>GO</td> <td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaParCentralizada">]
cXMLSedex := cXMLSedex + [ <td>MG</td> <td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaImparCentralizada">]
cXMLSedex := cXMLSedex + [ <td>MS</td> <td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaParCentralizada">]
cXMLSedex := cXMLSedex + [ <td>MT</td> <td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaImparCentralizada">]
cXMLSedex := cXMLSedex + [ <td>PE</td> <td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaParCentralizada">]
cXMLSedex := cXMLSedex + [ <td>PR</td> <td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_amarela_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_vermelho_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaImparCentralizada">]
cXMLSedex := cXMLSedex + [ <td>RS</td> <td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaParCentralizada">]
cXMLSedex := cXMLSedex + [ <td>SP</td> <td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_amarela_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_vermelho_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaImparCentralizada">]
cXMLSedex := cXMLSedex + [ <td>SVAN</td> <td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><span></span></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaParCentralizada">]
cXMLSedex := cXMLSedex + [ <td>SVRS</td> <td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaImparCentralizada">]
cXMLSedex := cXMLSedex + [ <td>SVC-AN</td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><span></span></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr><tr class="linhaParCentralizada">]
cXMLSedex := cXMLSedex + [ <td>SVC-RS</td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td><span></span></td><td><img src="imagens/bola_verde_P.png" /></td><td><img src="imagens/bola_verde_P.png" /></td><td>-</td><td><span></span></td><td><img src="imagens/bola_verde_P.png" /></td>]
cXMLSedex := cXMLSedex + [ </tr>]
cXMLSedex := cXMLSedex + [</table>]
cXMLSedex := cXMLSedex + [</html>]
else
cXMLSedex := "" // Esvazia para pegar novo conteudo
oPg := _XMLHttpRequest() // TOLEAuto():New("Microsoft.XMLHTTP")
if oPg = nil
return nil
end
oPg:Open( "GET", cEanApi, .F. )
oPg:Send()
cXMLSedex := oPg:ResponseText // oPg:ResponseXML:xml
rMemoWrit( cPathDados + "\SEFAZ-"+charRem(":-/",time())+".STS", cXMLSedex )
endif
// TOleAuto() no Harbour e CreateObject() no xHarbour
if empty(cXMLSedex)
lSuccess := .f.
else
oXMLDoc := _MicrosoftXMLDOM() // TOLEAUTO():New("Microsoft.XMLDOM") // /* win_ole */ CreateObject( "Microsoft.XMLDOM" )
oTRDoc := _MicrosoftXMLDOM() // TOLEAUTO():New("Microsoft.XMLDOM") // /* win_ole */ CreateObject( "Microsoft.XMLDOM" )
oTDDoc := _MicrosoftXMLDOM() // TOLEAUTO():New("Microsoft.XMLDOM") // /* win_ole */ CreateObject( "Microsoft.XMLDOM" )
oXMLDoc:async := .f.
oTRDoc:async := .f.
oTDDoc:async := .f.
cXMLSedex := XMLGetFull( "table", cXMLSedex, .f., [ class="tabelaListagemDados] )
//lSuccess := oXMLDoc:load( cXMLSedex ) // Usado para carregar arquivo do disco
lSuccess := oXMLDoc:loadXML( cXMLSedex ) // Usado para receber string de conteudo
endif
if !lSuccess // se NAO abriu com sucesso...
VerifyINI( "Geral", "ForcaContingencia", "S", cPathDados+"\nfw.ini", .T. )
VerifyINI( "SEFAZ", "Status", "OFF", cPathDados+"\nfw.ini", .T. )
oWnd:oMsgBar:DelItem( oMsgItemCFaz )
oMsgItemCFaz := TMsgItem():New(oWnd:oMsgBar,,24,,,,.t.,,"level2",, "Informa SEFAZ status" )
oMsgItemCFaz:Refresh()
else
// Cria objeto principal
VerifyINI( "Geral", "ForcaContingencia", "N", cPathDados+"\nfw.ini", .T. )
VerifyINI( "SEFAZ", "Status", "ON", cPathDados+"\nfw.ini", .T. )
oTRTags := oXMLDoc:getElementsByTagName( "tr" )
aTRTags := {}
cTRTags := ""
for iTRTags = 2 to oTRTags:length
// Traz a linha TR
cTRTag := oTRTags:Item(iTRTags-1):xml
oTRDoc:loadXML( cTRTag )
oTDTags := oTRDoc:getElementsByTagName( "td" )
aTDCols := { "Autorizador", "Autorizacao", "Retorno", "Inutilizacao", "ConsStatus", "Status", "TempoMedio", "ConsCadastro", "RecepEventos" }
aTDTags := {}
cTDTags := ""
for iTDTags = 1 to oTDTags:length
// Traz a coluna TD
cTDTag := XMLGet( "td", oTDTags:Item(iTDTags-1):xml )
cTDTag := strTran( cTDTag, [<img src="imagens/], "" )
cTDTag := strTran( cTDTag, [.png"/>], "" )
cTDTag := strTran( cTDTag, [<span></span>], "-" )
cTDTag := strTran( cTDTag, [bola_], "" )
cTDTag := strTran( cTDTag, [_P], "" )
if iTDTags = 1
ciTDTag := cTDTag
endif
cTDTags := cTDTags + ["] + alltrim(aTDCols[iTDTags]) + [":"] + cTDTag + ["] + iif(iTDTags=9,[],[,] + CRLF )
aadd( aTDTags, cTDTag )
next
cTRTags := cTRTags + [{] + CRLF + cTDTags + CRLF + [}] + iif(iTRTags=oTRTags:length,[],[, ] + CRLF )
aadd( aTRTags, aTDTags )
next
// ---------- Padrao de Pesquisa
cAutorizador := VerifyINI( "SEFAZ", "autorizador" , "SP", cPathRaiz+"\DEVELOP.ini", .F. )
cOperacao := VerifyINI( "SEFAZ", "operacao" , 6 , cPathRaiz+"\DEVELOP.ini", .F. )
// ---------- 1-Autorizador, 2-Autorizacao, 3-Retorno, 4-Inutilizacao, 5-ConsStatus, 6-Status, 7-TempoMedio, 8-ConsCadastro, 9-RecepEventos
nTPos := AScan( aTRTags, { | e | e[1] == cAutorizador } ) // Pega todos os status do autorizador configurado
cAutorizacao := VerifyINI( "SEFAZ", "Autorizacao" , aTRTags[nTPos,2], cPathRaiz+"\DEVELOP.ini", .F. )
cRetorno := VerifyINI( "SEFAZ", "Retorno" , aTRTags[nTPos,3], cPathRaiz+"\DEVELOP.ini", .F. )
cInutilizacao := VerifyINI( "SEFAZ", "Inutilizacao", aTRTags[nTPos,4], cPathRaiz+"\DEVELOP.ini", .F. )
cConsStatus := VerifyINI( "SEFAZ", "ConsStatus" , aTRTags[nTPos,5], cPathRaiz+"\DEVELOP.ini", .F. )
cStatus := VerifyINI( "SEFAZ", "Status" , aTRTags[nTPos,6], cPathRaiz+"\DEVELOP.ini", .F. )
cTempoMedio := VerifyINI( "SEFAZ", "TempoMedio" , aTRTags[nTPos,7], cPathRaiz+"\DEVELOP.ini", .F. )
cConsCadastro := VerifyINI( "SEFAZ", "ConsCadastro", aTRTags[nTPos,8], cPathRaiz+"\DEVELOP.ini", .F. )
cRecepEvento := VerifyINI( "SEFAZ", "RecepEvento" , aTRTags[nTPos,9], cPathRaiz+"\DEVELOP.ini", .F. )
//
oWnd:oMsgBar:DelItem( oMsgItemCFaz )
oMsgItemCFaz := TMsgItem():New(oWnd:oMsgBar,,24,,,,.t.,,"level1",, "Informa SEFAZ status" )
oMsgItemCFaz:Refresh()
endif
SysRefresh()
HB_GCALL( .T. ) // limpar o lixo na memoria .F. so se tiver lixo
//MemoryFlush()
RETURN nil
FUNCTION IsInternete()
LOCAL cIp, cVret := .F.
WsaStartUp()
cIp := GETHOSTBYNAME( "microsoft.com" )
cIp := GETHOSTBYNAME( "microsoft.com" )
WsaCleanUp()
// Seguranca caso o provedor da microsoft esteja fora do ar...
IF ( cIp <= "0.0.0.0" )
WsaStartUp()
cIp := GetHostByName( "google.com" )
cIp := GetHostByName( "google.com" )
WsaCleanUp()
ENDIF
MsgRun( cIp )
RETURN( cIp<>"0.0.0.0" )
FUNCTION IEGetSEFAZ( _uf_, _operacao_, _lista_ )
LOCAL aList := { ;
{ "BA", "verde", "verde", "verde", "verde", "verde", "verde", "verde", "verde" } , ;
{ "RJ", "verde", "verde", "verde", "verde", "verde", "verde", "verde", "verde" } , ;
{ "SP", "verde", "verde", "verde", "verde", "verde", "verde", "verde", "verde" } , ;
{ "MG", "verde", "verde", "verde", "verde", "verde", "verde", "verde", "verde" } , ;
{ "PR", "verde", "verde", "verde", "verde", "verde", "vermelho", "verde", "verde" } }
DEFAULT _lista_ := aList
cResName := "verde"
IF ( nPos := AScan( _lista_, { | e | e[1] == _uf_ } ) ) != 0
_cBola_ := _lista_[ nPos, _operacao_ ]
aCORList := { ;
{ "verde" , "LEVEL1" } , ;
{ "vermelho", "LEVEL2" } , ;
{ "amarela" , "LEVEL3" } }
IF ( nCPos := AScan( aCORList, { | e | e[1] == _cBola_ } ) ) != 0
cResName := strtran( cPathRaiz+"\imagens\" + aCORList[ nCPos, 2 ] + ".bmp", "\\", "\" )
cResName := aCORList[ nCPos, 2 ]
ENDIF
IF !("verde" $ aCORList[ nCPos, 2 ]) // Forcando contingencia
//VerifyINI( "Geral", "ForcaContingencia", "S", cPathRaiz+"\nfw.ini", .T. )
VerifyINI( "SEFAZ", "Status", "OFF", cPathRaiz+"\nfw.ini", .T. )
ELSE
//VerifyINI( "Geral", "ForcaContingencia", "N", cPathRaiz+"\nfw.ini", .T. )
VerifyINI( "SEFAZ", "Status", "ON", cPathRaiz+"\nfw.ini", .T. )
ENDIF
ENDIF
RETURN { _cBola_, cResName, _lista_ }
/* ********************************
if file("DSPNBLDD.DBF")
use DSPNBLDD shared
do while .not. eof()
if _uf_ $ DSPNBLDD->Autorizado // := aTRTags[i,1]
if _operacao_ = 2 ; _cBola_ := alltrim( DSPNBLDD->Autorizaca ) ; exit ; endif // := aTRTags[i,2]
if _operacao_ = 3 ; _cBola_ := alltrim( DSPNBLDD->Retorno ) ; exit ; endif // := aTRTags[i,3]
if _operacao_ = 4 ; _cBola_ := alltrim( DSPNBLDD->Inutilizac ) ; exit ; endif // := aTRTags[i,4]
if _operacao_ = 5 ; _cBola_ := alltrim( DSPNBLDD->ConsStatus ) ; exit ; endif // := aTRTags[i,5]
if _operacao_ = 6 ; _cBola_ := alltrim( DSPNBLDD->Status ) ; exit ; endif // := aTRTags[i,6]
if _operacao_ = 7 ; _cBola_ := alltrim( DSPNBLDD->TempoMedio ) ; exit ; endif // := aTRTags[i,7]
if _operacao_ = 8 ; _cBola_ := alltrim( DSPNBLDD->ConsCadast ) ; exit ; endif // := aTRTags[i,8]
if _operacao_ = 9 ; _cBola_ := alltrim( DSPNBLDD->RecepEvent ) ; exit ; endif // := aTRTags[i,9]
endif
dbSkip()
enddo
use // DSPNBLDD // verde-LEVEL1 vermelho-LEVEL2 amarela-LEVEL3
else
_bar_:SetText( "Nao encontrei DSPNBLDD.DBF" )
_bar_:Refresh()
endif
RETURN "\sistemas\contrib\tsbrowse\bitmaps\" + iif(_cBola_="amarela","LEVEL3",iif(_cBola_="vermelho","LEVEL2",iif(_cBola_="verde","LEVEL1","LEVEL1"))) + ".bmp"
******************************** */
Function XMLGet( XMLField, XMLFile )
XMLField := alltrim( XMLField )
XMLFieldINI := At( "<"+XMLField+">", XMLFile ) + len( "<"+XMLField+">" )
XMLFieldEND := At( "</"+XMLField+">", XMLFile ) - XMLFieldINI
return substr( XMLFile, XMLFieldINI, XMLFieldEND )
Function XMLGetFull( XMLField, XMLFile, lXMLFull, XMLCompl )
default lXMLFull := .f., XMLCompl := ""
XMLField := alltrim( XMLField )
XMLFieldINI := At( [<]+XMLField+XMLCompl, XMLFile )
XMLFieldEND := At( XMLField+[>], substr( XMLFile, XMLFieldINI, len( XMLFile ) - XMLFieldINI ) )
return iif( !lXMLFull, "", "<"+XMLField+">" ) + substr( XMLFile, XMLFieldINI, XMLFieldEND + len(XMLField) ) + iif( !lXMLFull, "", "</" + XMLField + ">" )
function VerifyINI( _section_, _entry_, _var_, _inifile_, _grava_ )
oIni := TIni():New( _inifile_ )
if _grava_ = nil; _grava_ := .f.; endif
if _grava_ = .t.
oIni:Set( _section_, _entry_, _var_ )
endif
return oIni:Get( _section_, _entry_, _var_, _var_ )
Aqui se usa os bitmaps bola amarela, vermelha e verde contidas na pasta imagens do Fivewin.
Na configuração da barra de status do meu sistema acrescentei o semaforo de bitmaps e ativei um timer para verificar de tempos em tesmpos a situação.
Faça uma análise e veja se compensa a implementação.
@braços à todos.