NFS-e PMSP

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

eduardomc00
Usuário Nível 1
Usuário Nível 1
Mensagens: 43
Registrado em: 07 Out 2014 18:29
Localização: São Paulo

NFS-e PMSP

Mensagem por eduardomc00 »

Senhores, boa tarde!

Na NFS-e de SP, a legislação exige uma assinatura prévia da informação contida no RPS.

Essa assinatura é uma String formada por alguns campos e segue o seguintes passos:


String: "31000000OL03 00000000000120070103TNN00000000205000000000000050000002658100013167474254”
2º - Converta a cadeia de caracteres ASCII para bytes.
3º - Gere o HASH (array de bytes) utilizando SHA1.
4º - Assine o HASH (array de bytes) utilizando RSA-SHA1.


Enfim, eu não consegui fazer isto via harbour. Criei um EXE em C# para realizar esta operação.

Após tudo isso deve-se assinar o XML como na NF-e ( Isto faço via harbour).

Se eu utilizar o certificado A1, funciona perfeitamente.
Com A3, o Sistema emite a primeira nota, mas na segunda me retorna um erro de segurança.

pesquisando, vi que é pq o meu Sistema está pedindo novamente a senha do certificado, na emissão da segunda nota.

mas isso ocorre justamente pq há uma outra aplicação acessando o certificado (O Exe auxiliar).

Dúvida:

Alguém tem a rotina para assinar esta string via harbour?!

Sabendo que se eu fechar a aplicação e abri-la novamente funciona,
alguém sabe se há alguma forma de zerar os dados da CAPICOM utilizado anteriormente para não ter conflito.?



Desde já agradeço


Eduardo Campos.
geovaninogueira
Usuário Nível 1
Usuário Nível 1
Mensagens: 2
Registrado em: 11 Jun 2014 08:55
Localização: Itaquaquecetuba/SP

NFS-e PMSP

Mensagem por geovaninogueira »

Boa Tarde.

Amigos também estou com essa dúvida.

Atenciosamente GeovaniNs.
Avatar do usuário
HASA
Colaborador
Colaborador
Mensagens: 1088
Registrado em: 01 Set 2003 19:50
Localização: São Paulo
Contato:

NFS-e PMSP

Mensagem por HASA »

:-O
Eduardo e Geovani, acredito que no forum do HBNFE tenha essa parte, e assim que tiver funcionando tenho interesse em comprar os fontes para incorporar ao meu sistema interno de emissão de nfs que ainda digitamos no site da PMSP.
:)Pos
HASA
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

NFS-e PMSP

Mensagem por JoséQuintas »

Sério isso?

Então vou cobrar.... kkkkkk

Antes de mais nada um ponto interessante:
Eu uso NF-e de SP.
Transmito meus "RPS" pra lá.
Mas não uso nenhum certificado, assim como não uso pra ter acesso ao site.


Agora via webservice:
Segue o esquema parecido com NFe.
Assinatura do bloco, transmitir pra webservice, pegar retorno.
Ou seja, exatamente o que a classe pra NFE faz.
Lógico, a classe ainda não conhece os endereços de NFSe, por isso não está pronta pra fazer isso.

Quanto à assinatura de NFSe, acho que acrescentei no ano passado, de acordo com o que um usuário me informou.
Como nunca usei, não posso confirmar se está ok.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

NFS-e PMSP

Mensagem por JoséQuintas »

É esta parte, quem puder confirmar se realmente é SP:

Código: Selecionar todos

      { "<infPedidoCancelamento", "</Pedido>" }, ;               // NFSE ABRASF Cancelamento
      { "<LoteRps",               "</EnviarLoteRpsEnvio>" }, ;   // Lote NFSE
      { "<infRps",                "</Rps>" } }                   // NFSE ABRASF
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
HASA
Colaborador
Colaborador
Mensagens: 1088
Registrado em: 01 Set 2003 19:50
Localização: São Paulo
Contato:

NFS-e PMSP

Mensagem por HASA »

:(
José, já tentei com o UniNfs, e torço para que um dia o pessoal do acbr libere um monitor "GOLD" com essa possibilidade, por isso estou já no desespero para automatizar isso aqui na empresa PMSP, como o SAT está me consumindo para caramba, as NFS vão ficando para depois, casa de ferreiro...
:xau
HASA
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

NFS-e PMSP

Mensagem por JoséQuintas »

Como eu emito tudo de uma vez, sem problemas enviar "manualmente".
Gero o arquivo em txt, entro no site, e clico em enviar RPS.
Por ser microempresa, não precisa certificado pra nada disso.

Por XML, aí entra certificado, assinatura, e webservice.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
HASA
Colaborador
Colaborador
Mensagens: 1088
Registrado em: 01 Set 2003 19:50
Localização: São Paulo
Contato:

NFS-e PMSP

Mensagem por HASA »

:-O
José por força do SAT tenho certificado digital da empresa sem problemas nesse sentido, o caso é enviar mesmo, aguarderei, estou enrolado mesmo.
:xau
HASA
Avatar do usuário
HASA
Colaborador
Colaborador
Mensagens: 1088
Registrado em: 01 Set 2003 19:50
Localização: São Paulo
Contato:

NFS-e PMSP

Mensagem por HASA »

:))
Amigos, Giovani e Eduardo, não deixem de postar as novidades ok.
:)Pos
HASA
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

NFS-e PMSP

Mensagem por JoséQuintas »

Deixei passar uma questão inicial:
Sabendo que se eu fechar a aplicação e abri-la novamente funciona,
alguém sabe se há alguma forma de zerar os dados da CAPICOM utilizado anteriormente para não ter conflito.?
Talvez fechar o "repositório" de certificados após o uso.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
eduardomc00
Usuário Nível 1
Usuário Nível 1
Mensagens: 43
Registrado em: 07 Out 2014 18:29
Localização: São Paulo

NFS-e PMSP

Mensagem por eduardomc00 »

Ainda não resolvi este problema...
eu sai um pouco deste projeto porque estava ficando louco kkkk
mas logo logo retornarei com novidades!
Avatar do usuário
HASA
Colaborador
Colaborador
Mensagens: 1088
Registrado em: 01 Set 2003 19:50
Localização: São Paulo
Contato:

NFS-e PMSP

Mensagem por HASA »

:{

Força Edu...

X:)

HASA
Avatar do usuário
HASA
Colaborador
Colaborador
Mensagens: 1088
Registrado em: 01 Set 2003 19:50
Localização: São Paulo
Contato:

NFS-e PMSP

Mensagem por HASA »

Eduardo Campos, Bom dia, você teve algum progresso? É possível disponibilizar ou negociar o que tem, gostaria de emitir as nfs da empresa, não é para os meus clientes e para eu quebrar uns espetos de pau 8-|

:{
HASA
eduardomc00
Usuário Nível 1
Usuário Nível 1
Mensagens: 43
Registrado em: 07 Out 2014 18:29
Localização: São Paulo

NFS-e PMSP

Mensagem por eduardomc00 »

HASA Boa tarde,

Estou meio sem tempo pra tentar esse problema que relatei no inicio e o código está meio sujo ainda e somente para PMSP:
Mas se quiser usar, com certificado A1 funciona !!!
Alias, descobri que na minha máquina funciona com o A3 tbm, mas na máquina da menina do financeiro, não funciona. :'(

Enfim...

Código: Selecionar todos


//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

//////////////////////////////////////
FUNCTION NFSE_Emite( cAlias              ,;
                     lShowMessage        ,;
                     lEmiteAntesDeGravar ,;
                     hrps                ,;
                     hcod_servic         ,;
                     hcod_c              ,;
                     hnome               ,;
                     hcnpj_cpf           ,;
                     hquantidade         ,;
                     hvl_u_nff           ,;
                     hvl_deducoes        ,;
                     haliq_iss           ,;
                     hvl_iss             ,;
                     hpis                ,;
                     hvl_pis             ,;
                     hcofins             ,;
                     hvl_cofins          ,;
                     hvl_inss            ,;
                     hvl_irpj            ,;
                     hvl_csll            ,;
                     hvl_nota            ,;
                     hobs_serv1          ,;
                     hobs_serv2          ,;
                     hobs_serv3          ,;
                     hobs_serv4          ,;
                     hobs_serv5          ,;
                     hobs_serv6           )
//////////////////////////////////////

LOCAL lReturn     := .T.
LOCAL oNFSE       := NFSE()

LOCAL aRodape     := Fil_aRodape()
LOCAL cRazao      := ALLTRIM(StringDel('.',Fil_RazaoSoc()))
LOCAL cCNPJ       := ALLTRIM(STRTRAN(STRTRAN(STRTRAN(aRodape[ FIL_RODAPE_CNPJ ], '.'), '/'), '-'))
LOCAL cIM         := ALLTRIM(STRTRAN(STRTRAN(aRodape[ FIL_RODAPE_IM ], '.'), '-'))
LOCAL cMunicipio  := aRodape[ FIL_RODAPE_CID ]
LOCAL cUF         := aRodape[ FIL_RODAPE_UF  ]
LOCAL cCodMun     := ValidaCidadeIbge( cMunicipio, cUF )

LOCAL aRetorno
LOCAL aRetorno2

LOCAL cNf_sv
LOCAL cCod_verificacao
LOCAL cRPS
LOCAL aMsgErr

LOCAL nChoose := 0

LDEFAULT lShowMessage TO .F.

NFSE_NEW_InitVars()

oNFSE:ohbNFe := oNfe

// Cabecalho
oNFSE:cab_CodCidade                   := VAL( cCodMun ) // 3550308
oNFSE:cab_CPFCNPJRemetente            := cCNPJ          // "99999999999999"
oNFSE:cab_RazaoSocialRemetente        := cRazao         // "RAZAO"
oNFSE:cab_dtInicio                    := DATE()
oNFSE:cab_dtFim                       := DATE()
oNFSE:cab_QtdRPS                      := 1
oNFSE:cab_ValorTotalServicos          := VAL( StringDel( " ", STRTRAN( hvl_nota, ",", "." ) ) )
oNFSE:cab_ValorTotalDeducoes          := VAL( StringDel( " ", STRTRAN( hvl_deducoes, ",", "." ) ) )
oNFSE:cab_Versao                      := 1
oNFSE:cab_MetodoEnvio                 := 'WS'
oNFSE:cab_VersaoComponente            := '6.0004'

// Rps
oNFSE:rps_InscricaoMunicipalPrestador := cIM     // "99999999"
oNFSE:rps_RazaoSocialPrestador        := cRazao  // "razao"
oNFSE:rps_TipoRPS                     := 'RPS'
oNFSE:rps_SerieRPS                    := 'OL03'

oNFSE:rps_NumeroRPS                   := VAL( hrps )
oNFSE:rps_DataEmissaoRPS              := DATE()
oNFSE:rps_SituacaoRPS                 := "N"     // OU "C" Normal/Cancelada

GNum_Set( "GN_RPS_NUM", oNFSE:rps_NumeroRPS+1 )

CLI->( WOrder( "COD_C" ) )
CLI->( WSeek( PADR(hcod_c,18) ) )

oNFSE:rps_SeriePrestacao              := '99'
oNFSE:rps_InscricaoMunicipalTomador   := "-"                                                // "-"
oNFSE:rps_CPFCNPJTomador              := ALLTRIM( Clear_Slashs( hcnpj_cpf ) )               // "99999999999"
oNFSE:rps_RazaoSocialTomador          := ALLTRIM( hnome           )                         // "Eduardo Martins de Campos"
oNFSE:rps_DocTomadorEstrangeiro       := ""
oNFSE:rps_TipoLogradouroTomador       := ALLTRIM( "RUA"           )                         // "Rua"
oNFSE:rps_LogradouroTomador           := ALLTRIM( CLI->endereco   )                         // "Lorena"
oNFSE:rps_NumeroEnderecoTomador       := ALLTRIM( CLI->nro        )                         // "32"
oNFSE:rps_ComplementoEnderecoTomador  := ALLTRIM( CLI->complemen  )                         // ""
oNFSE:rps_TipoBairroTomador           := "."                                                // "."
oNFSE:rps_BairroTomador               := ALLTRIM( CLI->bairro     )                         // "jd. xxxxxxxxxxx"
oNFSE:rps_CidadeTomador               := VAL(ValidaCidadeIbge( CLI->cidade, cli->estado ))  // 3550308
oNFSE:rps_CidadeTomadorDescricao      := ALLTRIM( CLI->cidade     )                         // "sao paulo"
oNFSE:rps_CEPTomador                  := ALLTRIM( Clear_Slashs(CLI->cep) )                  // "09381440"
oNFSE:rps_EmailTomador                := ALLTRIM( CLI->e_mail     )                         // ""
oNFSE:rps_CodigoAtividade             := ALLTRIM( Clear_Slashs(hcod_servic) )               // "02798"
oNFSE:rps_AliquotaAtividade           := VAL(haliq_iss)                                     // 0
oNFSE:rps_TipoRecolhimento            := "A"                                                // "A" // OU R
oNFSE:rps_MunicipioPrestacao          := VAL(ValidaCidadeIbge( CLI->cidade, cli->estado ))  // 3550308
oNFSE:rps_MunicipioPrestacaoDescricao := ALLTRIM( cMunicipio )                              // "SAO PAULO"
oNFSE:rps_Operacao                    := "A"                                                // "A"
oNFSE:rps_Tributacao                  := "T"                                                // "T"
oNFSE:rps_ValorPIS                    := hvl_pis                                            // 0
oNFSE:rps_ValorCOFINS                 := VAL(hvl_cofins)                                    // 0
oNFSE:rps_ValorINSS                   := VAL(hvl_inss)                                      // 0
oNFSE:rps_ValorIR                     := VAL(hvl_irpj)                                      // 0
oNFSE:rps_ValorCSLL                   := VAL(hvl_csll)                                      // 0
oNFSE:rps_AliquotaPIS                 := hpis                                               // 0
oNFSE:rps_AliquotaCOFINS              := hcofins                                            // 0
oNFSE:rps_AliquotaINSS                := 0                                                  // 0
oNFSE:rps_AliquotaIR                  := SetaCros( GC_NF_A_IRRF )                           // 0
oNFSE:rps_AliquotaCSLL                := SetaCros( GC_NF_A_IRRF )                           // 0

SET DECIMALS TO 4
oNFSE:cValorCargaTributaria           := ALLTRIM( StringDel( " ", STRTRAN( hvl_iss, ",", "." ) ) )
oNFSE:cPercentualCargaTributaria      := NTRIM( VAL(StringDel( " ", STRTRAN( haliq_iss, ",", "." ) ) )/100 )
SET DECIMALS TO 2

// Registros de Itens da RPS
oNFSE:Itens_DiscriminacaoServico := hobs_serv1 + " " +;
                                    hobs_serv2 + " " +;
                                    hobs_serv3 + " " +;
                                    hobs_serv4 + " " +;
                                    hobs_serv5 + " " +;
                                    hobs_serv6                     // "Desenvolvimento de Web Site Pessoal"
                                    
oNFSE:Itens_Quantidade           := hquantidade                                   // 1
oNFSE:Itens_ValorUnitario        := hvl_u_nff                                     // 0
oNFSE:Itens_ValorTotal           := hquantidade * hvl_u_nff                       // 0
oNFSE:Itens_Tributavel           := hquantidade                                   // "1"

// Registro das Deducoes
oNFSE:Deducao_DeducaoPor         := "Percentual"

aRetorno := oNFSE:Registro_Cabecalho()  // Monta o Cabe‡alho do XML

IF !aRetorno['STATUS']
   WinMsg(aRetorno['MSG'])
   RETURN( .F. )
ENDIF

aRetorno := oNFSE:Registro_RPS()                  // Registra o Servi‡o Prestado no XML
IF !aRetorno['STATUS']
   WinMsg(aRetorno['MSG'])
   RETURN( .F. )
ENDIF

aRetorno := oNFSE:Registro_Deducao_RPS(.F.,.F.)   // Se houver Dedu‡Æo adiciona
IF !aRetorno['STATUS']
   WinMsg(aRetorno['MSG'])
   RETURN( .F. )
ENDIF

aRetorno := oNFSE:Finaliza_RPS()
IF !aRetorno['STATUS']
   WinMsg(aRetorno['MSG'])
   RETURN( .F. )
ENDIF

aRetorno := oNFSE:Assina_XML()
IF !aRetorno['STATUS']
   WinMsg(aRetorno['MSG'])
   RETURN( .F. )
ENDIF

aRetorno := oNFSE:ComunicaWebService()

IF !aRetorno['STATUS']
   WinMsg(aRetorno['MSG'])
   RETURN( .F. )
ENDIF

cNf_sv           := hbNFe_PegaDadosXML("NumeroNFe",         AlteraCaracteres(aRETORNO["XML"], .T.) )
cCod_verificacao := hbNFe_PegaDadosXML("CodigoVerificacao", AlteraCaracteres(aRETORNO["XML"], .T.) )
cRPS             := hbNFe_PegaDadosXML("NumeroRPS",         AlteraCaracteres(aRETORNO["XML"], .T.) )

aRetorno2 := oNFSE:LeRetorno(aRETORNO["XML"])

IF aRetorno2['STATUS'] .AND. cNf_sv != NIL
   // OK.
      
ELSE

   aMsgErr := { "NÆo foi poss¡vel emitir a NFS-e."              ,;
                ""                                              ,;
                "Codigo: "    + LTRIM(aRetorno2['CODIGO'])      ,;
                ""                                              ,;
                "Descri‡Æo: " + LTRIM( aRetorno2['DESCRICAO'] ) ,;
                ""                                              ,;
                "Mensagem: "  + LTRIM( aRetorno2['MSG'] )        }

   WinMsgMU( aMsgErr )
   Envia_Fail_2_Vendor_Gestor_GAcum_Op( .F., EMAIL_2_NF_99, aMsgErr, cAlias, NAT_OP_NOVO_VENDA, oNFSE:Itens_ValorTotal )

   lReturn := .F.
   
ENDIF

RETURN( lReturn )
/////////////////
// EOF NFSE_Emite()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

////////////////////////////////
FUNCTION NFSE_Cancelar( cAlias )
////////////////////////////////

LOCAL lReturn := .F.
LOCAL oNFSE   := NFSE()
LOCAL oInfo

LOCAL aRodape     := Fil_aRodape()
LOCAL cCNPJ       := ALLTRIM(STRTRAN(STRTRAN(STRTRAN(aRodape[ FIL_RODAPE_CNPJ ], '.'), '/'), '-'))
LOCAL cIM         := ALLTRIM(STRTRAN(STRTRAN(aRodape[ FIL_RODAPE_IM ], '.'), '-'))
LOCAL cMunicipio  := aRodape[ FIL_RODAPE_CID ]
LOCAL cUF         := aRodape[ FIL_RODAPE_UF  ]
LOCAL cCodMun     := ValidaCidadeIbge( cMunicipio, cUF )
LOCAL cNf

LOCAL aRetorno
LOCAL aMsgErr

NFSE_NEW_InitVars()

oNFSE:ohbNFe := oNfe

(cAlias)->( DBGOTOP() )

WHILE (cAlias)->( !EOF() )

   IF !IsServico( (cAlias)->identidade ) .OR. EMPTY( (cAlias)->nf_sv )
      (cAlias)->( DBSKIP() )
      LOOP
   ENDIF
   
   IF 1 == WinAsk( { "Deseja realmente cancelar a NFS-e "+ALLTRIM( (cAlias)->nf_sv )+"?"},;
                     { "Sim", "NÆo" } )


      oInfo := MsgInfo( "Cancelando NFS-e :" + (cAlias)->nf_sv )
      
      oNFSE:cab_CodCidade                   := VAL( cCodMun )
      oNFSE:cab_CPFCNPJRemetente            := cCNPJ
      oNFSE:rps_InscricaoMunicipalPrestador := cIM
      oNFSE:numero_nota                     := VAL((cAlias)->nf_sv)
      oNFSE:codigo_verificacao              := (cAlias)->cod_verifi
      aRetorno := oNFSE:CancelaNFSe()

      MsgInfoClose( @oInfo )
      
      IF aRETORNO['STATUS']

         WinMsg( "NFS-e " + (cAlias)->nf_sv + " cancelada com SUCESSO." )

      ENDIF
      
   ENDIF
   (cAlias)->( DBSKIP() )
   
ENDDO



RETURN( lReturn )
// EOF NFSE_Cancelar()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

///////////////////////////
FUNCTION NFSE_NEW_InitVars()
///////////////////////////

LOCAL aRodape    := Fil_aRodape()
LOCAL cMunicipio := ALLTRIM( aRodape[ FIL_RODAPE_CID ] )
LOCAL cDir

LOCAL cDirBkp_PC_TEC := "C:\"

LOCAL cDateFormat := SET( _SET_DATEFORMAT )

cUF := aRodape[ FIL_RODAPE_UF ]

IF WSet( LPK_B_PC_TEC ) .OR. WSet( LPK_B_PC_DEMO ) .OR. WSet( LPK_B_PC_TREINAMENTO )
   cMunicipio := "SAO PAULO"
   cUF:= "SP"
ENDIF

cSerialCert := SetaCros( GC_NFE_NS_CERTIF )

SET DATE FORMAT TO "DD.MM.YYYY"

cDir := "NIVELXMLNFSE\" + ALLTRIM( STR(YEAR( DATE() ),4) )
WDirMake( cDir )

cDir += "\" + ALLTRIM( STR( MONTH( DATE() ) ) )
WDirMake( cDir )

WDirMake( cDir +"\XML"   )
WDirMake( cDir +"\CANC"  )
WDirMake( cDir +"\PDF"   )
WDirMake( cDir +"\INUTI" )
WDirMake( cDir +"\DPEC"  )
WDirMake( cDir +"\ENVRES")

IF WSet( LPK_B_PC_TEC )

   // NOTA: Somente em PC TEC.
   // Ser  mantido um Back-up dos XML's do Sistema no Disco C: de cada computador
   // para não perder o numerador.

   cDirBkp_PC_TEC := "C:\"
   WDirMake( cDirBkp_PC_TEC +"\WSoft_XMLs_PC_Tec"   )
   WDirMake( cDirBkp_PC_TEC +"\WSoft_XMLs_PC_Tec\"+ ALLTRIM( STR(YEAR( DATE() ),4) ) )
   WDirMake( cDirBkp_PC_TEC +"\WSoft_XMLs_PC_Tec\"+ ALLTRIM( STR(YEAR( DATE() ),4)+ "\" + ALLTRIM( STR( MONTH( DATE() ) ) ) ) )

   cDirBkp_PC_TEC := "C:\WSoft_XMLs_PC_Tec\"+ ALLTRIM( STR(YEAR( DATE() ),4) ) + "\" + ALLTRIM( STR( MONTH( DATE() ) ) )

   WDirMake( cDirBkp_PC_TEC +"\XML"   )

ENDIF

SET( _SET_DATEFORMAT, cDateFormat )

oNfe     := hbNfe()
// oFuncoes := hbNFeFuncoes()

////
// Escolhe Certificado Digital
//
IF cSerialCert == NIL .OR. EMPTY( cSerialCert )
   NFE_NEW_LerCertificado(.T.)
ENDIF
//
// Escolhe Certificado Digital
////

oNfe:cPastaSchemas := WSet( CPK_B_PARENT_DISK_DIR )+"\NIVELSCHEMAS"
oNFe:cSerialCert   := cSerialCert
oNFe:nSOAP         := HBNFE_MXML
oNFe:cUFWS         := sUfCodeIBGE(cUF)        // UF WebService

IF SetaFil( GF_NF_H_VERAO ) == IS_ON
   oNFe:cUTC       := '-02:00'  // utc de verao -2  de inverno -3
ELSE
   oNFe:cUTC       := '-03:00'  // utc de verao -2  de inverno -3
ENDIF

IF SetaCros( GC_NFE_MODE ) == WS_NFE_TP_AMB_HOMOLOGACAO ;
   .OR. ;
   SetaCros( GC_NFE_MODE ) == WS_NFE_TP_AMB_TESTE

   oNFe:tpAmb := "2" // TESTE/HOMOLOGAۂO

ELSE

   oNFe:tpAmb := "1" // PRODUۂO

ENDIF

oNFe:empresa_tpImp     := IF ( SetaCros( GC_NFE_PORTRAIT )=="R","1", "2" )
oNFe:tpEmis            := SetaCros( GC_NFE_TPEMIS ) // tpEmis //normal/scan/dpec/fs/fsda

oNFe:empresa_UF        := sUfCodeIBGE(cUF)
oNFe:empresa_cMun      := cMunicipio
oNFe:versaoDadosCCe    := '1.00'
oNFe:versaoDados       := "3.10"
oNFe:versaoSistema     := "1.0"


oNFe:pastaNFe          := cDir+"\XML"

IF WSet( LPK_B_PC_TEC )
   oNFe:pastaNFeBKP    := cDirBkp_PC_TEC + "\XML"
ENDIF

oNFe:pastaCancelamento := cDir+"\CANC"
oNFe:pastaPDF          := cDir+"\PDF"
oNFe:pastaInutilizacao := cDir+"\INUTI"
oNFe:pastaDPEC         := cDir+"\DPEC"
oNFe:pastaEnvRes       := cDir+"\ENVRES"
oNFe:cSiteEmitente     := "asdasdasd"
oNFe:cDesenvolvedor    := "Desenvolvido por Eduardo Campos"

RETURN( .T. )
/////////////////
// EOF NFSE_NEW_InitVars()
eduardomc00
Usuário Nível 1
Usuário Nível 1
Mensagens: 43
Registrado em: 07 Out 2014 18:29
Localização: São Paulo

NFS-e PMSP

Mensagem por eduardomc00 »

NFSE.prg

Código: Selecionar todos

// ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
// ³                              NFSE.PRG                                   ³
// ³         NFS-e  Gera Nota Fiscal de Servi‡o Eletr“nica                   ³
// ³                         VIA PROGRAMA WSOFT                              ³
// ³                           29/04/2016                                    ³
// ³                              EMC                                        ³
// ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

#include "common.ch"
#include "hbclass.ch"
#include "hbnfe.ch"

#include "wsmode.ch"
#include "wsnatop.ch"
#include "wscalc_f.ch"
#include "wsfile.ch"
#include "wsecf.ch"
#include "wsged.ch"

#include "inkey.ch"
#include "fileio.ch"
#include "directry.ch"
#include "dll.ch"

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

//////////
CLASS NFSE
//////////

   DATA oFuncoes     INIT hbNFeFuncoes()
   // DATA oCTe_GERAIS  INIT oCTe_GERAIS()
   DATA ohbNFe
   DATA oSigner
   DATA Xml
   
   // Cabecalho
   DATA cab_CodCidade
   DATA cab_CPFCNPJRemetente
   DATA cab_RazaoSocialRemetente
   DATA cab_dtInicio
   DATA cab_dtFim
   DATA cab_QtdRPS
   DATA cab_ValorTotalServicos
   DATA cab_ValorTotalDeducoes
   DATA cab_Versao Init 1
   DATA cab_MetodoEnvio Init 'WS'
   DATA cab_VersaoComponente Init '6.0004'
   
   // Rps
   DATA rps_InscricaoMunicipalPrestador
   DATA rps_RazaoSocialPrestador
   DATA rps_TipoRPS Init 'RPS'
   DATA rps_SerieRPS Init 'NF' 
   DATA rps_NumeroRPS
   DATA rps_DataEmissaoRPS
   DATA rps_SituacaoRPS
   DATA rps_SerieRPSSubstituido
   DATA rps_NumeroRPSSubstituido
   DATA rps_NumeroNFSeSubstituida
   DATA rps_DataEmissaoNFSeSubstituida Init CTOD('01/01/1900')
   DATA rps_SeriePrestacao Init '99'
   DATA rps_InscricaoMunicipalTomador
   DATA rps_CPFCNPJTomador
   DATA rps_RazaoSocialTomador
   DATA rps_DocTomadorEstrangeiro
   DATA rps_TipoLogradouroTomador
   DATA rps_LogradouroTomador
   DATA rps_NumeroEnderecoTomador
   DATA rps_ComplementoEnderecoTomador
   DATA rps_TipoBairroTomador
   DATA rps_BairroTomador
   DATA rps_CidadeTomador
   DATA rps_CidadeTomadorDescricao
   DATA rps_CEPTomador
   DATA rps_EmailTomador
   DATA rps_CodigoAtividade
   DATA rps_AliquotaAtividade
   DATA rps_TipoRecolhimento
   DATA rps_MunicipioPrestacao
   DATA rps_MunicipioPrestacaoDescricao
   DATA rps_Operacao
   DATA rps_Tributacao
   DATA rps_ValorPIS
   DATA rps_ValorCOFINS
   DATA rps_ValorINSS
   DATA rps_ValorIR
   DATA rps_ValorCSLL
   DATA rps_AliquotaPIS
   DATA rps_AliquotaCOFINS
   DATA rps_AliquotaINSS
   DATA rps_AliquotaIR
   DATA rps_AliquotaCSLL
   DATA rps_DescricaoRPS
   DATA rps_DDDPrestador
   DATA rps_TelefonePrestador
   DATA rps_DDDTomador
   DATA rps_TelefoneTomador
   DATA rps_MotCancelamento
   DATA rps_CPFCNPJIntermediario

   // V10.0.K1292
   DATA cValorCargaTributaria
   DATA cPercentualCargaTributaria
   // V10.0.K1292

   // Registros de Itens da RPS
   DATA Itens_DiscriminacaoServico
   DATA Itens_Quantidade
   DATA Itens_ValorUnitario
   DATA Itens_ValorTotal
   DATA Itens_Tributavel   
   
   // Registro das Deducoes
   DATA Deducao_DeducaoPor
   DATA Deducao_TipoDeducao
   DATA Deducao_CPFCNPJReferencia
   DATA Deducao_NumeroNFReferencia
   DATA Deducao_ValorTotalReferencia
   DATA Deducao_PercentualDeduzir
   DATA Deducao_ValorDeduzir
   
   DATA numero_nota
   DATA codigo_verificacao
   DATA motivo
   
   METHOD Registro_Cabecalho()
   METHOD Registro_RPS()
   METHOD Registro_Itens_RPS(lABRE,lFECHA)
   METHOD Registro_Deducao_RPS(lABRE,lFECHA)
   METHOD Assina_XML()

   METHOD Finaliza_RPS()

   METHOD Gera_Chave_SHA1()
   METHOD Gera_Chave_SHA1_Cancelamento()
   METHOD DataToYYYY_MM_DD(dDAT,lTIME)
   METHOD DataToYYYYMMDD(dDAT)
   METHOD LinkWebService(cServ)
   METHOD ComunicaWebService(cMETHOD)
   METHOD ctPegaCNCertificado()
   METHOD LeRetorno(cRET)
   METHOD CancelaNFSe()
   METHOD ValidaXML()

ENDCLASS
////////
// EOC NFSE()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

//////////////////////////////////////
METHOD Registro_Cabecalho() Class NFSE
//////////////////////////////////////

LOCAL aRETORNO:=HASH()
LOCAL cXML:='', cARQ:=''
LOCAL nHandle

aRETORNO['STATUS']:=.F.
aRETORNO['MSG']:=''

IF ::cab_CodCidade=NIL .OR. ::cab_CodCidade<=0
   aRETORNO['MSG']:='Favor informar o código do município'
ENDIF
IF ::cab_CPFCNPJRemetente=NIL .OR. EMPTY(::cab_CPFCNPJRemetente)
   aRETORNO['MSG']:='Favor informar o CPF / CNPJ do Remetente'
ENDIF
IF ::cab_RazaoSocialRemetente=NIL .OR. EMPTY(::cab_RazaoSocialRemetente)
   aRETORNO['MSG']:='Favor informar a razão social do Remetente'
ENDIF
IF ::cab_dtInicio=NIL .OR. DAY(::cab_dtInicio)<=0
   aRETORNO['MSG']:='Favor informar a data inicial da remessa'
ENDIF
IF ::cab_dtFim=NIL .OR. DAY(::cab_dtFim)<=0
   aRETORNO['MSG']:='Favor informar a data final da remessa'
ENDIF
IF ::cab_ValorTotalServicos=NIL
   ::cab_ValorTotalServicos:=0
ENDIF
IF ::cab_ValorTotalDeducoes=NIL
   ::cab_ValorTotalDeducoes:=0
ENDIF

IF !EMPTY(aRETORNO['MSG'])
   RETURN(aRETORNO)
ENDIF

cXML+='<PedidoEnvioLoteRPS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.prefeitura.sp.gov.br/nfe">'

cXML+=   '<Cabecalho Versao="1" xmlns="">'
cXML+=      '<CPFCNPJRemetente><CNPJ>'+ALLTRIM(::cab_CPFCNPJRemetente)+'</CNPJ></CPFCNPJRemetente>'
cXML+=      '<transacao>false</transacao>'
cXML+=      '<dtInicio>'+::DataToYYYY_MM_DD(::cab_dtInicio)+'</dtInicio>'
cXML+=      '<dtFim>'+::DataToYYYY_MM_DD(::cab_dtFim)+'</dtFim>'
cXML+=      '<QtdRPS>'+ALLTRIM(STR(::cab_QtdRPS))+'</QtdRPS>'
cXML+=      '<ValorTotalServicos>'+ALLTRIM(STR(::cab_ValorTotalServicos))+'</ValorTotalServicos>'
cXML+=      '<ValorTotalDeducoes>'+ALLTRIM(STR(::cab_ValorTotalDeducoes))+'</ValorTotalDeducoes>'
cXML+=   '</Cabecalho>'

cARQ:=::ohbNFe:pastaEnvRes+'\NFSe'+ALLTRIM(::cab_CPFCNPJRemetente)+DTOS(DATE())+STRTRAN(LEFT(TIME(),8),':')+'.xml'

nHandle := FCREATE(cARQ)
FWRITE(nHandle, cXML)
FCLOSE( nHandle )
::XML := cARQ
aRETORNO['STATUS']:=.T.
aRETORNO['XML']:=cARQ
aRETORNO['MSG']:='XML criado em '+cARQ

RETURN(aRETORNO)
////////////////
// EOM Registro_Cabecalho()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

////////////////////////////////
METHOD Registro_RPS() Class NFSE
////////////////////////////////

LOCAL aRETORNO:=HASH()
LOCAL cXML:='', cARQ:=''
LOCAL nHandle

aRETORNO['STATUS']:=.F.
aRETORNO['MSG']:=''

IF ::Xml=NIL .OR. EMPTY(::Xml)
   aRETORNO['MSG']:='Arquivo XML com o registro do cabeçalho não informado.'
ENDIF
IF ::rps_InscricaoMunicipalPrestador=NIL .OR. EMPTY(::rps_InscricaoMunicipalPrestador)
   aRETORNO['MSG']:='Favor Informar a Inscrição Municipal do Prestador. Verificar regra de preenchimento do campo no Anexo 03.'
ENDIF
IF ::rps_RazaoSocialPrestador=NIL .OR. EMPTY(::rps_RazaoSocialPrestador)
   aRETORNO['MSG']:='Favor Informar a Razão Social do Prestador.'
ENDIF
IF ::rps_TipoRPS=NIL .OR. EMPTY(::rps_TipoRPS)
   aRETORNO['MSG']:='Favor Informar o Tipo de RPS Padrão "RPS".'
ENDIF
IF ::rps_SerieRPS=NIL .OR. EMPTY(::rps_SerieRPS)
   aRETORNO['MSG']:='Favor Informar a Série do RPS - Padrão "NF".'
ENDIF
IF ::rps_NumeroRPS=NIL .OR. ::rps_NumeroRPS<=0
   aRETORNO['MSG']:='Favor Informar o Número da RPS.'
ENDIF
IF ::rps_NumeroRPS=NIL .OR. ::rps_NumeroRPS<=0
   aRETORNO['MSG']:='Favor Informar o Número da RPS.'
ENDIF
IF ::rps_DataEmissaoRPS=NIL .OR. DAY(::rps_DataEmissaoRPS)<=0
   aRETORNO['MSG']:='Favor Informar o Data de Emissão da RPS.'
ENDIF
IF ::rps_SituacaoRPS=NIL .OR. EMPTY(::rps_SituacaoRPS)
   aRETORNO['MSG']:='Favor Informar a Situação da RPS - "N"-Normal, "C"-Cancelada.'
ENDIF
IF ::rps_SerieRPSSubstituido=NIL
   ::rps_SerieRPSSubstituido:=''
ENDIF

IF ::rps_SituacaoRPS=NIL .OR. EMPTY(::rps_SituacaoRPS)
   aRETORNO['MSG']:='Favor Informar a Situação da RPS - "N"-Normal, "C"-Cancelada.'
ENDIF
IF ::rps_NumeroRPSSubstituido=NIL
   ::rps_NumeroRPSSubstituido:=0
ENDIF
IF ::rps_NumeroNFSeSubstituida=NIL
   ::rps_NumeroNFSeSubstituida:=0
ENDIF
IF ::rps_DataEmissaoNFSeSubstituida=NIL .OR. DAY(::rps_DataEmissaoNFSeSubstituida)<=0
   aRETORNO['MSG']:='Favor Informar a Data de emissão da NFSe Formato= AAAA-MM-DD. Se não for substituto preencher com "01/01/1900".'
ENDIF
IF ::rps_SeriePrestacao=NIL .OR. EMPTY(::rps_SeriePrestacao)
   aRETORNO['MSG']:='Favor Informar o Número do equipamento emissor do RPS ou série de prestação. Caso não utilize a série, preencha o campo com o valor ‘99’ que indica modelo único. Caso queira utilizar o campo série para indicar o número do equipamento emissor do RPS deve-se solicitar liberação da prefeitura.'
ENDIF
IF ::rps_InscricaoMunicipalTomador=NIL .OR. EMPTY(::rps_InscricaoMunicipalTomador)
   aRETORNO['MSG']:='Favor Informar a Inscrição Municipal do Tomador. Caso o tomador não for do municipio não preencher, caso o tomador for do município preencher com a Inscrição Municipal formatada Seguindo Anexo 03.'
ENDIF
IF ::rps_CPFCNPJTomador=NIL .OR. EMPTY(::rps_CPFCNPJTomador)
   aRETORNO['MSG']:='Favor Informar o CPF ou CNPJ do Tomador. Ex: "00000000000191"'
ENDIF
IF ::rps_RazaoSocialTomador=NIL .OR. EMPTY(::rps_RazaoSocialTomador)
   aRETORNO['MSG']:='Favor Informar a Razão Social do Tomador'
ENDIF
IF ::rps_DocTomadorEstrangeiro=NIL
   ::rps_DocTomadorEstrangeiro:=''
ENDIF
IF ::rps_TipoLogradouroTomador=NIL .OR. EMPTY(::rps_TipoLogradouroTomador)
   aRETORNO['MSG']:='Favor Informar o Tipo de Logradouro do Tomador. Campo de preenchimento livre. Verificar exemplos no anexo 04.'
ENDIF
IF ::rps_LogradouroTomador=NIL .OR. EMPTY(::rps_LogradouroTomador)
   aRETORNO['MSG']:='Favor Informar o Logradouro do Tomador.'
ENDIF
IF ::rps_NumeroEnderecoTomador=NIL .OR. EMPTY(::rps_NumeroEnderecoTomador)
   aRETORNO['MSG']:='Favor Informar o Numero de Endereço do Tomador.'
ENDIF
IF ::rps_ComplementoEnderecoTomador=NIL
   ::rps_ComplementoEnderecoTomador:=''
ENDIF
IF ::rps_TipoBairroTomador=NIL .OR. EMPTY(::rps_TipoBairroTomador)
   aRETORNO['MSG']:='Favor Informar o Tipo de Bairro do Tomador . Campo de preenchimento livre. Verificar exemplos no Anexo 05.'
ENDIF
IF ::rps_BairroTomador=NIL .OR. EMPTY(::rps_BairroTomador)
   aRETORNO['MSG']:='Favor Informar o Bairro do Tomador.'
ENDIF
IF ::rps_CidadeTomador=NIL .OR. ::rps_CidadeTomador<=0
   aRETORNO['MSG']:='Favor Informar o Código da Cidade do Tomador padrão SIAFI. (Confira o nome da cidade no cadastro do cliente)'
ENDIF
IF ::rps_CidadeTomadorDescricao=NIL .OR. EMPTY(::rps_CidadeTomadorDescricao)
   aRETORNO['MSG']:='Favor Informar o Nome da Cidade do Tomador.'
ENDIF
IF ::rps_CEPTomador=NIL .OR. EMPTY(::rps_CEPTomador)
   aRETORNO['MSG']:='Favor Informar o CEP do Tomador Ex: "37900000".'
ENDIF
IF ::rps_EmailTomador=NIL .OR. EMPTY(::rps_EmailTomador)
   ::rps_EmailTomador:='-'
ENDIF
IF ::rps_CodigoAtividade=NIL .OR. EMPTY(::rps_CodigoAtividade)
   aRETORNO['MSG']:='Favor Informar o Código da Atividade da RPS. (Confira o codigo CNAE no cadastro do cliente)'
ENDIF
IF ::rps_AliquotaAtividade=NIL
   ::rps_AliquotaAtividade:=0
ENDIF
IF ::rps_TipoRecolhimento=NIL .OR. EMPTY(::rps_TipoRecolhimento)
   aRETORNO['MSG']:='Favor Informar o Tipo de Recolhimento - "A" – A Receber, "R" - Retido na Fonte.'
ENDIF
IF ::rps_MunicipioPrestacao=NIL .OR. ::rps_MunicipioPrestacao<=0
   aRETORNO['MSG']:='Favor Informar o Código do Município de Prestação – Padrão SIAFI.'
ENDIF
IF ::rps_MunicipioPrestacao=NIL .OR. ::rps_MunicipioPrestacao<=0
   aRETORNO['MSG']:='Favor Informar o Código do Município de Prestação – Padrão SIAFI.'
ENDIF
IF ::rps_MunicipioPrestacaoDescricao=NIL .OR. EMPTY(::rps_MunicipioPrestacaoDescricao)
   aRETORNO['MSG']:='Favor Informar o Município de Prestação do Serviço.'
ENDIF
IF ::rps_Operacao=NIL .OR. EMPTY(::rps_Operacao)
   aRETORNO['MSG']:='Favor Informar a Operação - "A"-Sem Dedução, "B"-Com Dedução/Materiais, "C" - Imune/Isenta de ISSQN, "D" - Devolução/Simples Remessa, "J" - Intemediação.'
ENDIF
IF ::rps_Tributacao=NIL .OR. EMPTY(::rps_Tributacao)
   aRETORNO['MSG']:='Favor Informar a Tributação: C - Isenta de ISS, E - Não Incidência no Município, F - Imune, K - Exigibilidd Susp.Dec.J/Proc.A, N - Não Tributável, T – Tributável, G - Tributável Fixo, H - Tributável S.N., M - Micro Empreendedor Individual (MEI).'
ENDIF
IF ::rps_ValorPIS=NIL
   ::rps_ValorPIS:=0.00
ENDIF
IF ::rps_ValorCOFINS=NIL
   ::rps_ValorCOFINS:=0.00
ENDIF
IF ::rps_ValorINSS=NIL
   ::rps_ValorINSS:=0.00
ENDIF
IF ::rps_ValorIR=NIL
   ::rps_ValorIR:=0.00
ENDIF
IF ::rps_ValorCSLL=NIL
   ::rps_ValorCSLL:=0.00
ENDIF
IF ::rps_AliquotaPIS=NIL
   ::rps_AliquotaPIS:=0.00
ENDIF
IF ::rps_AliquotaCOFINS=NIL
   ::rps_AliquotaCOFINS:=0.00
ENDIF
IF ::rps_AliquotaINSS=NIL
   ::rps_AliquotaINSS:=0.00
ENDIF
IF ::rps_AliquotaIR=NIL
   ::rps_AliquotaIR:=0.00
ENDIF
IF ::rps_AliquotaCSLL=NIL
   ::rps_AliquotaCSLL:=0.00
ENDIF
IF ::rps_DescricaoRPS=NIL
   ::rps_DescricaoRPS:=''
ENDIF
IF ::rps_DDDPrestador=NIL
   ::rps_DDDPrestador:=''
ENDIF
IF ::rps_TelefonePrestador=NIL
   ::rps_TelefonePrestador:=''
ENDIF
IF ::rps_DDDTomador=NIL
   ::rps_DDDTomador:=''
ENDIF
IF ::rps_TelefoneTomador=NIL
   ::rps_TelefoneTomador:=''
ENDIF
IF ::rps_MotCancelamento=NIL
   ::rps_MotCancelamento:=''
ENDIF
IF ::rps_CPFCNPJIntermediario=NIL
   ::rps_CPFCNPJIntermediario:=''
ENDIF

IF !EMPTY(aRETORNO['MSG'])
   RETURN(aRETORNO)
ENDIF

cXML:=MEMOREAD(::Xml)
FERASE(::Xml)

cAssinatura:=::Gera_Chave_SHA1()
cXML+=      '<RPS xmlns="">'  //'<RPS Id="rps:2">'
cXML+=         '<Assinatura>'+cAssinatura+'</Assinatura>'
cXML+=         '<ChaveRPS>'
cXML+=            '<InscricaoPrestador>'+ALLTRIM(::rps_InscricaoMunicipalPrestador)+'</InscricaoPrestador>'
cXML+=            '<SerieRPS>'+ALLTRIM(::rps_SerieRPS)+'</SerieRPS>'
cXML+=            '<NumeroRPS>'+ALLTRIM(STR(::rps_NumeroRPS))+'</NumeroRPS>'
cXML+=         '</ChaveRPS>'
cXML+=         '<TipoRPS>'+ALLTRIM(::rps_TipoRPS)+'</TipoRPS>'
cXML+=         '<DataEmissao>'+::DataToYYYY_MM_DD(::rps_DataEmissaoRPS,.F.)+'</DataEmissao>'
cXML+=         '<StatusRPS>'+ALLTRIM(::rps_SituacaoRPS)+'</StatusRPS>'
cXML+=         '<TributacaoRPS>'+ALLTRIM(::rps_Tributacao)+'</TributacaoRPS>'
cXML+=         '<ValorServicos>'+ALLTRIM(STR(::cab_ValorTotalServicos))+'</ValorServicos>'
cXML+=         '<ValorDeducoes>'+ALLTRIM(STR(::cab_ValorTotalDeducoes))+'</ValorDeducoes>'
cXML+=         '<CodigoServico>'+::rps_CodigoAtividade+'</CodigoServico>'
cXML+=         '<AliquotaServicos>'+ALLTRIM(STR(::rps_AliquotaAtividade))+'</AliquotaServicos>'
cXML+=         '<ISSRetido>false</ISSRetido>'

// V10.0.K1608
// cXML+=         '<CPFCNPJTomador><CPF>'+ALLTRIM(::rps_CPFCNPJTomador)+'</CPF></CPFCNPJTomador>'
IF LEN( ALLTRIM(::rps_CPFCNPJTomador) ) == 14
   cXML+=         '<CPFCNPJTomador><CNPJ>'+ALLTRIM(::rps_CPFCNPJTomador)+'</CNPJ></CPFCNPJTomador>'
ELSE
   cXML+=         '<CPFCNPJTomador><CPF>'+ALLTRIM(::rps_CPFCNPJTomador)+'</CPF></CPFCNPJTomador>'
ENDIF
// V10.0.K1608

cXML+=         '<RazaoSocialTomador>'+ALLTRIM(::rps_RazaoSocialTomador)+'</RazaoSocialTomador>'
cXML+=         '<EnderecoTomador>'
cXML+=            '<TipoLogradouro>'+ALLTRIM(::rps_TipoLogradouroTomador)+'</TipoLogradouro>'
cXML+=            '<Logradouro>'+ALLTRIM(::oFuncoes:parseEncode(::rps_LogradouroTomador))+'</Logradouro>'
cXML+=            '<NumeroEndereco>'+ALLTRIM(::rps_NumeroEnderecoTomador)+'</NumeroEndereco>'
cXML+=            '<ComplementoEndereco>'+ALLTRIM(::oFuncoes:parseEncode(::rps_ComplementoEnderecoTomador))+'</ComplementoEndereco>'
cXML+=            '<Bairro>'+ALLTRIM(::oFuncoes:parseEncode(::rps_BairroTomador))+'</Bairro>'
cXML+=            '<Cidade>'+ALLTRIM(STR(::rps_CidadeTomador))+'</Cidade>'
cXML+=            '<UF>'+ALLTRIM("SP")+'</UF>'
cXML+=            '<CEP>'+ALLTRIM(::rps_CEPTomador)+'</CEP>'
cXML+=         '</EnderecoTomador>'
cXML+=         '<EmailTomador>'+ALLTRIM(::oFuncoes:parseEncode(::rps_EmailTomador))+'</EmailTomador>'
cXML+=         '<Discriminacao>'+ALLTRIM(::Itens_DiscriminacaoServico)+'</Discriminacao>'

// V10.0.K1292
cXML+=         '<ValorCargaTributaria>'+::cValorCargaTributaria+'</ValorCargaTributaria>'
cXML+=         '<PercentualCargaTributaria>'+::cPercentualCargaTributaria+'</PercentualCargaTributaria>'
cXML+=         '<FonteCargaTributaria>P.I.085/14</FonteCargaTributaria>'
// V10.0.K1292

cXML+=      '</RPS>'

cXML:=::oFuncoes:RemoveAcentuacao(cXML)

nHandle := FCREATE(::XML)
FWRITE(nHandle, cXML)
FCLOSE( nHandle )

aRETORNO['STATUS']:=.T.
aRETORNO['XML']:=::XML
aRETORNO['MSG']:='XML criado em '+::XML
RETURN(aRETORNO)
////////////////
// EOM Registro_RPS()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

//////////////////////////////////////////////////
METHOD Registro_Itens_RPS(lABRE,lFECHA) Class NFSE
//////////////////////////////////////////////////

LOCAL aRETORNO:=HASH()
LOCAL cXML:=''
LOCAL nHandle

aRETORNO['STATUS']:=.F.
aRETORNO['MSG']:=''

IF ::Xml=NIL .OR. EMPTY(::Xml)
   aRETORNO['MSG']:='Arquivo XML com o registro do cabeçalho e RPS não informado.'
ENDIF
IF ::Itens_DiscriminacaoServico=NIL .OR. EMPTY(::Itens_DiscriminacaoServico)
   aRETORNO['MSG']:='Favor informar a Discriminação do Serviço.'
ENDIF
IF ::Itens_Quantidade=NIL .OR. ::Itens_Quantidade<=0
   aRETORNO['MSG']:='Favor informar a Quantidade do serviço tomado.'
ENDIF
IF ::Itens_ValorUnitario=NIL .OR. ::Itens_ValorUnitario<=0
   aRETORNO['MSG']:='Favor informar o Valor Unitário do serviço tomado.'
ENDIF
IF ::Itens_ValorTotal=NIL .OR. ::Itens_ValorTotal<=0
   aRETORNO['MSG']:='Favor informar o Valor total do serviço tomado.'
ENDIF
IF ::Itens_Tributavel=NIL
   ::Itens_Tributavel:=''
ENDIF

IF !EMPTY(aRETORNO['MSG'])
   RETURN(aRETORNO)
ENDIF

cXML:=MEMOREAD(::Xml)
FERASE(::Xml)

IF lABRE
   cXML+='<Itens>'
ENDIF   

IF lFECHA
   cXML+='</Itens>'
ENDIF   

nHandle := FCREATE(::Xml)
FWRITE(nHandle, cXML)
FCLOSE( nHandle )

aRETORNO['STATUS']:=.T.
aRETORNO['XML']:=::Xml
aRETORNO['MSG']:='XML criado em '+::Xml

RETURN(aRETORNO)
////////////////
// EOM Registro_Itens_RPS()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

/////////////////////////////////////////
METHOD Registro_Deducao_RPS(lABRE,lFECHA)
/////////////////////////////////////////

LOCAL aRETORNO:=HASH()
LOCAL cXML:=''
LOCAL nHandle

aRETORNO['STATUS']:=.F.
aRETORNO['MSG']:=''

IF ::Xml=NIL .OR. EMPTY(::Xml)
   aRETORNO['MSG']:='Arquivo XML com o registro do cabeçalho e RPS não informado.'
ENDIF

IF !EMPTY(aRETORNO['MSG'])
   RETURN(aRETORNO)
ENDIF

cXML:=MEMOREAD(::Xml)
FERASE(::Xml)

nHandle := FCREATE(::Xml)
FWRITE(nHandle, cXML)
FCLOSE( nHandle )

aRETORNO['STATUS']:=.T.
aRETORNO['XML']:=::Xml
aRETORNO['MSG']:='XML criado em '+::Xml

RETURN(aRETORNO)
////////////////
// EOM Registro_Deducao_RPS()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

////////////////////////////////
METHOD Finaliza_RPS() Class NFSE
////////////////////////////////

LOCAL aRETORNO:=HASH()
LOCAL cXML:=''
LOCAL nHandle
aRETORNO['STATUS']:=.F.
aRETORNO['MSG']:=''

IF ::Xml=NIL .OR. EMPTY(::Xml)
   aRETORNO['MSG']:='Arquivo XML com o registro do cabeçalho e RPS não informado.'
ENDIF

cXML:=MEMOREAD(::Xml)

FERASE(::Xml)

cXML+='<Signature></Signature>'

cXML+='</PedidoEnvioLoteRPS>'

nHandle := FCREATE(::Xml)
FWRITE(nHandle, cXML)
FCLOSE( nHandle )

aRETORNO['STATUS']:=.T.
aRETORNO['XML']:=::Xml
aRETORNO['MSG']:='XML criado em '+::Xml

RETURN(aRETORNO)
////////////////
// EOM Finaliza_RPS()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

//////////////////////////////
METHOD Assina_XML() Class NFSE
//////////////////////////////

LOCAL oDOMDoc, oXmldsig, oCert, oStoreMem, dsigKey, signedKey
LOCAL aRETORNO:=HASH()
LOCAL cXML:='', cXMLSig:=''
LOCAL PosIni:=0, PosFim:=0, nP:=0, nResult:=0
LOCAL nHandle

aRETORNO['STATUS']:=.F.
aRETORNO['MSG']:=''

IF ::Xml=NIL .OR. EMPTY(::Xml)
   aRETORNO['MSG']:='Arquivo XML com o registro do cabeçalho e RPS não informado.'
ENDIF
cXML:=MEMOREAD(::Xml)
FERASE(::Xml)

cXML:=STRTRAN(cXML,'<Signature></Signature>','<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">'+;
                                             '<SignedInfo>'+;
                                                '<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />'+;
                                                '<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />'+;
                                                '<Reference URI="">'+;
                                                   '<Transforms>'+;
                                                      '<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />'+;
                                                      '<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />'+;
                                                   '</Transforms>'+;
                                                   '<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />'+;
                                                   '<DigestValue>'+;
                                                  '</DigestValue>'+;
                                                '</Reference>'+;
                                             '</SignedInfo>'+;
                                             '<SignatureValue>'+;
                                             '</SignatureValue>'+;
                                             '<KeyInfo>'+;
                                                '<X509Data>'+;
                                                   '<X509Certificate>'+;
                                                   '</X509Certificate>'+;
                                                '</X509Data>'+;
                                             '</KeyInfo>'+;
                                          '</Signature>')

// Inicializa o objeto do DOMDocument
TRY
   oDOMDoc := win_oleCreateObject(_MSXML2_DOMDocument)
CATCH
   aRETORNO['MSG']:='Nao foi possível carregar ' + _MSXML2_DOMDocument
   RETURN(aRETORNO)
END
oDOMDoc:async = .F.
oDOMDoc:resolveExternals := .F.
oDOMDoc:validateOnParse  = .T.
oDOMDoc:preserveWhiteSpace = .T.

// inicializa o objeto do MXDigitalSignature
TRY
   oXmldsig := win_oleCreateObject( _MSXML2_MXDigitalSignature )
CATCH
   aRETORNO['MSG']:='Nao foi possível carregar ' +_MSXML2_MXDigitalSignature
   RETURN(aRETORNO)
END

nHandle := FCREATE(::ohbNFe:pastaEnvRes+"\edunfs.xml")
FWRITE( nHandle, cXML )
FCLOSE( nHandle )

// carrega o arquivo XML para o DOM
oDOMDoc:LoadXML(cXML)
IF oDOMDoc:parseError:errorCode<>0
   aRETORNO['MSG']:=' Assinar: Não foi possível carregar o documento pois ele não corresponde ao seu Schema'+HB_OsNewLine()+;
                    ' Linha: '              + STR(oDOMDoc:parseError:line)+HB_OsNewLine()+;
                    ' Caractere na linha: ' + STR(oDOMDoc:parseError:linepos)+HB_OsNewLine()+;
                    ' Causa do erro: '      + oDOMDoc:parseError:reason+HB_OsNewLine()+;
                    ' code: '               + STR(oDOMDoc:parseError:errorCode)
   RETURN(aRETORNO)
ENDIF

// Localiza as assinaturas no XML
oDOMDoc:setProperty('SelectionNamespaces',"xmlns:ds='http://www.w3.org/2000/09/xmldsig#'")
oXmldsig:signature := oDOMDoc:selectSingleNode('.//ds:Signature')
IF (oXmldsig:signature = nil)
   aRETORNO['MSG'] := 'É preciso carregar o template antes de assinar.'
   RETURN(aRETORNO)
ENDIF

// carrega o objeto do certificado digital
oCert:=::ohbNFe:pegaObjetoCertificado(::ohbNFe:cSerialCert)

IF oCert == Nil
   aRETORNO['MSG']  := 'Certificado não encontrado, Favor revisar a instalação do Certificado'
   RETURN(aRETORNO)
ENDIF

// cria o objeto de Store da capicom
oStoreMem := win_oleCreateObject('CAPICOM.Store')

// Aloca o certificado na memoria
TRY
   oStoreMem:open(_CAPICOM_MEMORY_STORE,'Memoria',_CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED)
CATCH oError
   aRETORNO['MSG']:='Falha ao alocar o certificado na memoria '+HB_OsNewLine()+ ;
                    'Error: '     + Transform(oError:GenCode, nil)   + ';' +HB_OsNewLine()+ ;
                    'SubC: '      + Transform(oError:SubCode, nil)   + ';' +HB_OsNewLine()+ ;
                    'OSCode: '    + Transform(oError:OsCode,  nil)   + ';' +HB_OsNewLine()+ ;
                    'SubSystem: ' + Transform(oError:SubSystem, nil) + ';' +HB_OsNewLine()+ ;
                    'Mensangem: ' + oError:Description
   RETURN(aRETORNO)
END

// Aloca o certificado na Capicom
TRY
   oStoreMem:Add(oCert)
CATCH oError
   aRETORNO['MSG']:='Falha ao aloca o certificado na memoria da Capicom '+HB_OsNewLine()+;
                    'Error: '     + Transform(oError:GenCode, nil)   + ';' +HB_OsNewLine()+;
                    'SubC: '      + Transform(oError:SubCode, nil)   + ';' +HB_OsNewLine()+;
                    'OSCode: '    + Transform(oError:OsCode,  nil)   + ';' +HB_OsNewLine()+;
                    'SubSystem: ' + Transform(oError:SubSystem, nil) + ';' +HB_OsNewLine()+;
                    'Mensangem: ' + oError:Description
   RETURN(aRETORNO)
END
oXmldsig:store:=oStoreMem

// Cria chave CSP
TRY
   dsigKey:=oXmldsig:createKeyFromCSP(oCert:PrivateKey:ProviderType, oCert:PrivateKey:ProviderName, oCert:PrivateKey:ContainerName, 0)
CATCH
   aRETORNO['MSG']:='Erro ao criar a chave do CSP, talvez o certificado não esteja instalado corretamente.'
   RETURN(aRETORNO)          
END
IF (dsigKey = nil)
   aRETORNO['MSG']:='Erro ao criar a chave do CSP.'
   RETURN(aRETORNO)
ENDIF

// Assina a chave do CSP
TRY
   signedKey:=oXmldsig:sign(dsigKey, 2)
CATCH
   aRETORNO['MSG']:='Erro ao assinar a chave do CSP, talvez o certificado não esteja instalado corretamente.'
   RETURN(aRETORNO)
END
IF signedKey=NIL
   aRETORNO['MSG']:='Assinatura Falhou.'
   RETURN(aRetorno)
ENDIF

// Trata o formato da estrutura do XML
cXMLSig := STRTRAN(STRTRAN(oDOMDoc:xml,CHR(10)),CHR(13))
PosIni  := AT('<SignatureValue>',cXMLSig)+len('<SignatureValue>')
cXMLSig := SUBS(cXMLSig,1,PosIni-1)+STRTRAN( SUBS(cXMLSig,PosIni,len(cXMLSig)), ' ', '' )
PosIni  := AT('<X509Certificate>',cXMLSig)-1
nP      := AT('<X509Certificate>',cXMLSig)
nResult := 0
DO WHILE nP<>0
   nResult := nP
   nP = WAT('<X509Certificate>',cXMLSig,nP+1)
ENDDO
PosFim := nResult
cXMLSig := SUBS(cXMLSig,1,PosIni)+SUBS(cXMLSig,PosFim,len(cXMLSig))
cXMLsig := STRTRAN( cXMLsig, 'Id="rps:1"', '' )

// grava o arquivo no disco
nHandle := FCREATE(::Xml)
FWRITE(nHandle, cXMLSig)
FCLOSE( nHandle )

aRETORNO['STATUS']:=.T.
aRETORNO['XML']:=::Xml
aRETORNO['MSG']:='XML assinado com sucesso em '+::Xml

RETURN(aRETORNO)
////////////////
// EOM Assina_XML()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

//////////////////////////////////
METHOD LinkWebService() Class NFSE
//////////////////////////////////

LOCAL cWeb:=''

IF ::cab_CodCidade=3550308 // SÆo Paulo-SP
   cWeb:='https://nfe.prefeitura.sp.gov.br/ws/lotenfe.asmx'
ENDIF
RETURN(cWeb)
////////////
// EOM LinkWebService()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

///////////////////////////////////////
METHOD ctPegaCNCertificado() Class NFSE
///////////////////////////////////////

LOCAL oStore, oResult, oCertificados
LOCAL cSubjectName:='', cCN:=''
LOCAL mI:=0

TRY
   oStore := win_oleCreateObject( "CAPICOM.Store" )
CATCH
END

IF oStore = Nil
   RETURN('')
ENDIF

oStore:open(_CAPICOM_CURRENT_USER_STORE,'My',_CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED)
oCertificados:=oStore:Certificates()
FOR mI=1 TO oCertificados:Count()
   IF oCertificados:Item(mI):SerialNumber = ::ohbNFe:cSerialCert
      cSubjectName := oCertificados:Item(mI):SubjectName
   ENDIF
NEXT
cCN:=''
FOR mI:=AT("CN=",cSubjectName)+3 TO LEN(cSubjectName)
   IF SUBS(cSubjectName,mI,1) == ","
      EXIT
   ENDIF
   cCN += SUBS(cSubjectName,mI,1)
NEXT
oCertificados := Nil
oStore := Nil
RETURN(cCN)
///////////
// EOM ctPegaCNCertificado()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

/////////////////////////////////////////////
METHOD ComunicaWebService(cMethod) Class NFSE
/////////////////////////////////////////////

LOCAL oServerWS
LOCAL oDOMDoc
LOCAL aRETORNO   := HASH()
LOCAL cCERT      := ''
LOCAL cUrlWS     := ''
LOCAL cXML       := {}
LOCAL cNameSpace := ""
LOCAL cRetXml

aRETORNO['STATUS']:=.F.
aRETORNO['MSG']:=''

IF ::Xml=NIL .OR. EMPTY(::Xml)
   aRETORNO['MSG']:='Arquivo XML assinado de RPS não informado.'
ENDIF

cXML := MEMOREAD(::Xml)
// FERASE(::Xml)

IF EMPTY(cXML)

   aRETORNO['MSG']:='Favor informar o arquivo de XML.'
   RETURN(aRETORNO)
   
ENDIF

IF cMethod == 'cancelar'

   cNameSpace := "CancelamentoNFeRequest"
   
ELSE

   IF .f. // WSet( LPK_B_PC_TEC ) // NÆo est  funcionando
      cNameSpace := "TesteEnvioLoteRPSRequest"
   ELSE
      cNameSpace := "EnvioLoteRPSRequest"
   ENDIF
   
ENDIF

cXML := '<?xml version="1.0" encoding="utf-8"?>' +;
             '<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +;
             'xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' +;
             'xmlns:soap12="http://schemas.xmlsoap.org/soap/envelope/">' +;
             '<soap12:Body>' +;
               '<'+cNameSpace+' xmlns="http://www.prefeitura.sp.gov.br/nfe">' +;
                 '<VersaoSchema>1</VersaoSchema>' +;
                 '<MensagemXML> ' +;
                 '<![CDATA[ ' + cXML +' ]]>'+;
                 '</MensagemXML>' +;
               '</'+cNameSpace+'>'+;
             '</soap12:Body>' +;
           '</soap12:Envelope>'



nHandle := FCREATE(::ohbNFe:pastaEnvRes+"\edunfs.xml")
FWRITE( nHandle, cXML )
FCLOSE( nHandle )


TRY

   // cCERT := ::ctPegaCNCertificado()
   cCERT := ::ohbNFe:pegaCNCertificado(SetaCros( GC_NFE_NS_CERTIF ))
   
CATCH
END

IF EMPTY(cCERT)

   aRETORNO['MSG']:='Não foi possível carregar as informações do certificado.'
   RETURN(aRETORNO)
   
ENDIF

cUrlWS:=::LinkWebService()

IF EMPTY(cUrlWS)

   aRETORNO['MSG']:='Webservice não localizado'
   RETURN(aRETORNO)
   
ENDIF

TRY

   oServerWS:=win_oleCreateObject( _MSXML2_ServerXMLHTTP )
   oServerWS:setOption( 3, 'CURRENT_USER\MY\'+cCERT )
   oServerWS:open('POST', cUrlWS, .F.)
   IF .F. // WSet( LPK_B_PC_TEC ) // NÆo est  funcionando
      oServerWS:setRequestHeader('SOAPAction', 'http://www.prefeitura.sp.gov.br/nfe/ws/testeenvio' )
   ELSE
      IF cMethod == 'cancelar'
         oServerWS:setRequestHeader('SOAPAction', 'http://www.prefeitura.sp.gov.br/nfe/ws/cancelamentoNFe' )
      ELSE
         oServerWS:setRequestHeader('SOAPAction', 'http://www.prefeitura.sp.gov.br/nfe/ws/envioLoteRPS' )
      ENDIF
   ENDIF
   
   oServerWS:setRequestHeader('Content-Type','text/xml; charset=utf-8')

CATCH

   aRETORNO['MSG']:='Não foi possível inicializar a conexão do webservice'
   RETURN(aRETORNO)
   
END

IF oServerWS=NIL
   aRETORNO['MSG']:='Não foi possível inicializar o objeto de conexão do webservice'
   RETURN(aRETORNO)
ENDIF

TRY

   oDOMDoc:=win_oleCreateObject(_MSXML2_DOMDocument)
   oDOMDoc:async = .F.
   oDOMDoc:validateOnParse  = .T.
   oDOMDoc:resolveExternals := .F.
   oDOMDoc:preserveWhiteSpace = .T.
   oDOMDoc:LoadXML(cXML)
   
CATCH

   aRETORNO['MSG']:='Não foi possível carregar o documento XML'
   RETURN(aRETORNO)
   
END   

IF oDOMDoc:parseError:errorCode <> 0

   aRETORNO['MSG']:='Não foi possível carregar o documento pois ele não corresponde ao seu Schema'+HB_OsNewLine()+;
                    ' Linha: '+STR(oDOMDoc:parseError:line)                                       +HB_OsNewLine()+;
                    ' Caractere na linha: '+STR(oDOMDoc:parseError:linepos)                       +HB_OsNewLine()+;
                    ' Causa do erro: '+oDOMDoc:parseError:reason                                  +HB_OsNewLine()+;
                    ' Code: '+STR(oDOMDoc:parseError:errorCode)
  RETURN(aRETORNO)
  
ENDIF

TRY

   oServerWS:send( oDOMDoc:xml )

CATCH e

   aRETORNO['MSG']:='Falha: Não foi possível conectar-se ao servidor do SEFAZ, Servidor inativo ou inoperante.'+HB_OsNewLine()+;
                    'Error: '+Transform(e:GenCode,nil)                                                     +';'+HB_OsNewLine()+;
                    'SubC: '+Transform(e:SubCode,nil)                                                      +';'+HB_OsNewLine()+;
                    'OSCode: '+Transform(e:OsCode,nil)                                                     +';'+HB_OsNewLine()+;
                    'SubSystem: '+Transform(e:SubSystem,nil)                                               +';'+HB_OsNewLine()+;
                    'Mensangem: '+e:Description
   Wint(aRETORNO['MSG'])
  RETURN(aRETORNO)
  
END

DO WHILE oServerWS:readyState <> 4

  millisec(500)
  
ENDDO

aRETORNO['MSG']:='Comunicação com o webservice finalizada com sucesso.'
aRETORNO['STATUS']:=.T.
aRETORNO['XML']:=oServerWS:responseText

nHandle := FCREATE(::ohbNFe:pastaEnvRes+"\eduret.xml")
FWRITE( nHandle, AlteraCaracteres(oServerWS:responseText, .T.) )
FCLOSE( nHandle )

oDOMDoc   :=Nil
oServerWS :=Nil

RETURN(aRETORNO)
////////////////
// EOM ComunicaWebService()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

///////////////////////////////
METHOD CancelaNFSe() Class NFSE
///////////////////////////////

LOCAL cXML:=''
LOCAL aRETORNO:=HASH()
LOCAL nHandle
aRETORNO['STATUS']:=.F.
aRETORNO['MSG']:=''

IF ::cab_CodCidade=NIL .OR. ::cab_CodCidade<=0
   aRETORNO['MSG']:='Favor informar o código do município'
ENDIF
IF ::cab_CPFCNPJRemetente=NIL .OR. EMPTY(::cab_CPFCNPJRemetente)
   aRETORNO['MSG']:='Favor informar o CPF / CNPJ do Remetente'
ENDIF
IF ::rps_InscricaoMunicipalPrestador=NIL .OR. EMPTY(::rps_InscricaoMunicipalPrestador)
   aRETORNO['MSG']:='Favor Informar a Inscrição Municipal do Prestador. Verificar regra de preenchimento do campo no Anexo 03.'
ENDIF
IF ::numero_nota=NIL .OR. ::numero_nota<=0
   aRETORNO['MSG']:='Favor Informar o número da nota a ser cancelada.'
ENDIF
// IF ::codigo_verificacao=NIL .OR. EMPTY(::codigo_verificacao)
//    aRETORNO['MSG']:='Favor Informar o código verificador.'
// ENDIF

IF !EMPTY(aRETORNO['MSG'])
   aRETORNO["STATUS"] := .F.
   RETURN(aRETORNO)
ENDIF


cXML += '<PedidoCancelamentoNFe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.prefeitura.sp.gov.br/nfe">'

cXML+= '<Cabecalho Versao="1" xmlns="">'
cXML+=    '<CPFCNPJRemetente>'
cXML+=       '<CNPJ>'+ALLTRIM(::cab_CPFCNPJRemetente)+'</CNPJ>'
cXML+=    '</CPFCNPJRemetente>'
cXML+=    '<transacao>true</transacao>'
cXML+= '</Cabecalho>'
cXML+= '<Detalhe xmlns="">'
cXML+=    '<ChaveNFe>'
cXML+=       '<InscricaoPrestador>'+ALLTRIM(::rps_InscricaoMunicipalPrestador)+'</InscricaoPrestador>'
cXML+=       '<NumeroNFe>'+ALLTRIM(STR(::numero_nota))+'</NumeroNFe>'
cXML+=    '</ChaveNFe>'
cXML+=    '<AssinaturaCancelamento>'+::Gera_Chave_SHA1_Cancelamento()+'</AssinaturaCancelamento>'
cXML+= '</Detalhe>'
cXML+=   '<Signature></Signature>'
cXML+= '</PedidoCancelamentoNFe>'

::Xml:=::ohbNFe:pastaEnvRes+'\NFSe_canc'+ALLTRIM(::cab_CPFCNPJRemetente)+DTOS(DATE())+STRTRAN(LEFT(TIME(),8),':')+'.xml'

nHandle := FCREATE(::Xml)
FWRITE(nHandle, cXML)
FCLOSE( nHandle )

aRETORNO:=::Assina_XML()
IF !aRETORNO['STATUS']
   RETURN(aRETORNO)
ENDIF

// aRETORNO:=::ValidaXML()
// IF !aRETORNO['STATUS']
//    RETURN(aRETORNO)
// ENDIF

aRETORNO:=::ComunicaWebService('cancelar')
IF !aRETORNO['STATUS']
   RETURN(aRETORNO)
ENDIF

aRETORNO:=::LeRetorno(aRETORNO['XML'])

IF !aRETORNO['STATUS']
   RETURN(aRETORNO)
ENDIF

RETURN(aRETORNO)
// EOM CancelaNFSe()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

/////////////////////////////////
METHOD LeRetorno(cRET) Class NFSE
/////////////////////////////////

LOCAL aRETORNO:=HASH()
aRETORNO['STATUS']:=.F.
aRETORNO['MSG']:=''

cRET:=STRTRAN(cRET,'<','<')
cRET:=STRTRAN(cRET,'>','>')
cRET:=STRTRAN(cRET,'"','"')

IF '<Erros>' $ cRET
   cRET:=::oFuncoes:pegaTag(cRET,'Erro')
   aRETORNO['CODIGO']:=::oFuncoes:pegaTag(cRET,'Codigo')
   aRETORNO['DESCRICAO']:=::oFuncoes:pegaTag(cRET,'Descricao')
   aRETORNO['MSG']:=aRETORNO['CODIGO']+'-'+aRETORNO['DESCRICAO']
ELSEIF '<Alertas>' $ cRET
   cRET:=::oFuncoes:pegaTag(cRET,'Alerta')
   aRETORNO['CODIGO']:=::oFuncoes:pegaTag(cRET,'Codigo')
   aRETORNO['DESCRICAO']:=::oFuncoes:pegaTag(cRET,'Descricao')
   aRETORNO['MSG']:=aRETORNO['CODIGO']+'-'+aRETORNO['DESCRICAO']
ELSEIF '>false<' $ cRET
   aRETORNO['STATUS']    := .F.
   aRETORNO['CODIGO']    := ::oFuncoes:pegaTag(cRET,'Codigo')
   aRETORNO['DESCRICAO'] := ::oFuncoes:pegaTag(cRET,'Descricao')
   aRETORNO['MSG']       := aRETORNO['DESCRICAO']
ELSE
   aRETORNO['STATUS']:=.T.
ENDIF

RETURN(aRETORNO)
////////////////
// EOM LeRetorno()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

/////////////////////////////
METHOD ValidaXML() Class NFSE
/////////////////////////////

LOCAL oDOMDoc, oSchema, ParseError
LOCAL aRETORNO:=HASH()
LOCAL cSchemaFilename:=''

aRETORNO['STATUS']:=.F.
aRETORNO['MSG']:=''

IF ::Xml=NIL .OR. EMPTY(::Xml)
   aRETORNO['MSG']:='Arquivo XML assinado de RPS não informado.'
ENDIF

cXML:=MEMOREAD(::Xml)
wint("VALIDA")
IF 'ReqEnvioLoteRPS' $ cXML // Envio de lote
   cXML:=STRTRAN(cXML,' xmlns:tipos="http://localhost:8080/WsNFe2/tp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://localhost:8080/WsNFe2/lote http://localhost:8080/WsNFe2/xsd/ReqEnvioLoteRPS.xsd"')
   cSchemaFilename := ::ohbNFe:cPastaSchemas+'\ReqEnvioLoteRPS.xsd'
ELSEIF 'ReqCancelamentoNFSe' $ cXML  // Cancelamento de NFSe
   cXML:=STRTRAN(cXML,' xmlns:tipos="http://localhost:8080/WsNFe2/tp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://localhost:8080/WsNFe2/lote http://localhost:8080/WsNFe2/xsd/ReqCancelamentoNFSe.xsd"')
   cSchemaFilename := ::ohbNFe:cPastaSchemas+'\ReqCancelamentoNFSe.xsd'
ENDIF

TRY
   oDOMDoc := CreateObject( _MSXML2_DOMDocument )
CATCH
   aRETORNO['MSG']:='Não foi possível carregar o MSXML para validação do XML.'
   RETURN(aRETORNO)
END

TRY
   oDOMDoc:async = .F.
   oDOMDoc:resolveExternals := .F.
   oDOMDoc:validateOnParse  = .T.
   oDOMDoc:LoadXML(cXML)
CATCH
   aRETORNO['MSG']:='Não foi possível carregar o arquivo XML para a validação.'
   RETURN(aRETORNO)
END   
IF oDOMDoc:parseError:errorCode <> 0 // XML não carregado
   aRETORNO['MSG']:='Não foi possível carregar o documento pois ele não corresponde ao seu Schema'+HB_OsNewLine()+;
                    'Linha: '+STR(oDOMDoc:parseError:line)                                        +HB_OsNewLine()+;
                    'Caractere na linha: '+STR(oDOMDoc:parseError:linepos)                        +HB_OsNewLine()+;
                    'Causa do erro: '+oDOMDoc:parseError:reason                                   +HB_OsNewLine()+;
                    'Code: '+STR(oDOMDoc:parseError:errorCode)
  RETURN(aRETORNO)
ENDIF

TRY
   oSchema := CreateObject( _MSXML2_XMLSchemaCache )
CATCH
   aRETORNO['MSG']:='Não foi possível carregar o MSXML para o schema do XML.'
   RETURN(aRETORNO)
END

IF !FILE(cSchemaFilename)
  aRETORNO['MSG']:='Arquivo do schema não encontrado '+cSchemaFilename
  RETURN(aRETORNO)
ENDIF

TRY
   oSchema:add( 'http://localhost:8080/WsNFe2/lote', cSchemaFilename )
CATCH oError
   aRETORNO['MSG']:='Falha '+HB_OsNewLine()+ ;
                    'Error: '+Transform(oError:GenCode, nil)       + ';' +HB_OsNewLine()+;
                    'SubC: '+Transform(oError:SubCode, nil)        + ';' +HB_OsNewLine()+;
                    'OSCode: '+Transform(oError:OsCode,  nil)      + ';' +HB_OsNewLine()+;
                    'SubSystem: '+Transform(oError:SubSystem, nil) + ';' +HB_OsNewLine()+;
                    'Mensangem: '+oError:Description
  RETURN(aRETORNO)
END

oDOMDoc:Schemas := oSchema
ParseError := oDOMDoc:validate
IF ParseError:errorCode <> 0
   aRetorno['nResult']  := ParseError:errorCode
   aRETORNO['MSG']  := ParseError:reason
   RETURN(aRetorno)
ENDIF
oDOMDoc := nil
ParseError := nil
oSchema := nil
aRETORNO['XML']:=::Xml
aRETORNO['STATUS']:=.T.

RETURN(aRETORNO)
////////////////
// EOM ValidaXML()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

///////////////////////////////////
METHOD Gera_Chave_SHA1() Class NFSE
///////////////////////////////////

LOCAL cRET:=''
LOCAL cCHA := PADL(ALLTRIM(::rps_InscricaoMunicipalPrestador),8,'0')
LOCAL aRetorno
LOCAL oDll
LOCAL oFuncoes := hbNFeFuncoes()

cCHA += PADR(ALLTRIM(::rps_SerieRPS),5,' ')
cCHA += STRZERO(::rps_NumeroRPS,12)
cCHA += ::DataToYYYYMMDD(::rps_DataEmissaoRPS)
cCHA += ALLTRIM(::rps_Tributacao)
cCHA += LEFT(ALLTRIM(::rps_SituacaoRPS),1)
cCHA += IF(ALLTRIM(LEFT(::rps_TipoRecolhimento,1))='A','N','S')

// V10.0.K1608
// cCHA += STRZERO(VAL(STRTRAN(STR((::cab_ValorTotalServicos-::cab_ValorTotalDeducoes)*100),'.')),15)  //STRZERO((::cab_ValorTotalServicos-::cab_ValorTotalDeducoes),15)
cCHA += STRZERO(VAL(STRTRAN(STR(INT((::cab_ValorTotalServicos-::cab_ValorTotalDeducoes)*100)),'.')),15)  //STRZERO((::cab_ValorTotalServicos-::cab_ValorTotalDeducoes),15)

cCHA += STRZERO(VAL(STRTRAN(STR(::cab_ValorTotalDeducoes*100,15),'.')),15)  //STRZERO(::cab_ValorTotalDeducoes/100,15)
cCHA += PADL(ALLTRIM(::rps_CodigoAtividade),5,'0')

IF LEN(ALLTRIM(::rps_CPFCNPJTomador)) == 11
   cCHA += "1" // CPF
ELSE
   cCHA += "2" // CNPJ
ENDIF

cCHA += PADL(ALLTRIM(::rps_CPFCNPJTomador),14,'0')

nHandle := FCREATE("StringParaAssinar.txt")
FWRITE(nHandle, ::ohbNFe:cSerialCert + CHR(13)+CHR(10)+ cCHA )
FCLOSE( nHandle )
WRunCMD( "AssinaRPS.EXE" )
cRET := MEMOREAD( "StringAssinada.txt" )

cRET := STRTRAN( cRET, CHR(13), "" )
cRET := STRTRAN( cRET, CHR(10), "" )

FERASE("StringParaAssinar.txt")
FERASE("StringAssinada.txt")

RETURN(oFuncoes:parseEncode( cRET ) )
/////////////////////////////////////
// EOM Gera_Chave_SHA1()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

////////////////////////////////////////////////
METHOD Gera_Chave_SHA1_Cancelamento() Class NFSE
////////////////////////////////////////////////

LOCAL cRET:=''
LOCAL cCHA := ""
LOCAL aRetorno
LOCAL oDll
LOCAL oFuncoes := hbNFeFuncoes()

cCHA+=PADL(ALLTRIM(::rps_InscricaoMunicipalPrestador),  8, '0' )
cCHA+=PADL( ALLTRIM(STR(::numero_nota))              , 12, '0' )

nHandle := FCREATE("StringParaAssinar.txt")

FWRITE(nHandle, ::ohbNFe:cSerialCert + CHR(13)+CHR(10)+ cCHA )
FCLOSE( nHandle )
WRunCMD( "AssinaRPS.EXE" )

cRET := MEMOREAD( "StringAssinada.txt" )
cRET := STRTRAN( cRET, CHR(13), "" )
cRET := STRTRAN( cRET, CHR(10), "" )
FERASE("StringParaAssinar.txt")
FERASE("StringAssinada.txt")

RETURN(oFuncoes:parseEncode( cRET ) )
/////////////////////////////////////
// EOM Gera_Chave_SHA1_Cancelamento()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

//////////////////////////////////////////////
METHOD DataToYYYY_MM_DD(dDAT,lTIME) Class NFSE
//////////////////////////////////////////////

LOCAL cRET:=ALLTRIM(STR(YEAR(dDAT)))+'-'+STRZERO(MONTH(dDAT),2)+'-'+STRZERO(DAY(dDAT),2)
IF lTIME=NIL
  lTIME:=.F.
ENDIF
IF lTIME
   cRET+='T'+LEFT(TIME(),8)
ENDIF
RETURN(cRET)
////////////
// EOM DataToYYYY_MM_DD()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

//////////////////////////////////////
METHOD DataToYYYYMMDD(dDAT) Class NFSE
//////////////////////////////////////

LOCAL cRET:=ALLTRIM(STR(YEAR(dDAT)))+STRZERO(MONTH(dDAT),2)+STRZERO(DAY(dDAT),2)

RETURN(cRET)
////////////
// EOM DataToYYYY_MM_DD()

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

//////////////////////////////////////
FUNCTION AlteraCaracteres(c, lInverte)
//////////////////////////////////////

LDEFAULT lInverte TO .F.

IF lInverte
   c := STRTRAN( c, ">"   , ">")
   c := STRTRAN( c, "<"   , "<")
   c := STRTRAN( c, "&"  , "&")
   c := STRTRAN( c, """ , '"')
   c := STRTRAN( c, "&apos;" , "'")
ELSE
   c := STRTRAN( c, ">", ">"   )
   c := STRTRAN( c, "<", "<"   )
   c := STRTRAN( c, "&", "&"  )
   c := STRTRAN( c, '"', """ )
   c := STRTRAN( c, "'", "&apos;" )
ENDIF

RETURN( c )
///////////
// EOF AlteraCaracteres()



Responder