CODIGO FONTE NF ELETRONICA ATUALIZADA 22-02-10
Quero melhora-lo. Estou com pouco tempo só posso desenvolve-lo a noite, e nem sempre todos os dias, também levarei o projeto no blog
owlix.wordpress.com.
aqui está:
[c]
Imports System.Xml
Imports System.Security.Cryptography.Xml
Imports System.Security.Cryptography.X509Certificates
Namespace MyNFe
<ComClass(Init.ClassId, Init.InterfaceId, Init.EventsId)> _
Public Class Init
#Region [Ô]COM GUIDs[Ô]
Public Const ClassId As String = [Ô]5c506b5b-5b3d-4bd2-bc64-2502c4716324[Ô]
Public Const InterfaceId As String = [Ô]a242b6b8-f82a-4972-84fc-741f44edb85b[Ô]
Public Const EventsId As String = [Ô]2dfb5b2e-e831-4faa-b226-8d9a76eedae8[Ô]
#End Region
Private vWebServiceXMLResponse As String
Private vAno As String
Private vChNFe As String
Private vCNPJ As String
Private vCStat As String
Private vCStatInicial As String
Private vCUF As String
Private vDhRecbto As String
Private vDhRetorno As String
Private vDigVal As String
Private vMod As String
Private vNNFFin As String
Private vNNFIni As String
Private vNProt As String
Private vNRec As String
Private vSerie As String
Private vTMed As String
Private vTpAmb As String
Private vTpAmbInicial As String
Private vVerAplic As String
Private vVerAplicInicial As String
Private vXMotivo As String
Private vXMotivoInicial As String
Private vXObs As String
Private vSubjectCertificate As String
Private vURLWSNfeRecepcao As String
Private vURLWSNfeRetRecepcao As String
Private vURLWSNfeCancelamento As String
Private vURLWSNfeInutilizacao As String
Private vURLWSNfeConsultaNF As String
Private vURLWSNfeStatusServico As String
Private vGlobalTpAmb As String
Private WriteOnly Property WebServiceXMLResponse() As XmlDocument
Set(ByVal value As XmlDocument)
Me.vWebServiceXMLResponse = value.OuterXml
Dim AnoTagList As XmlNodeList = value.GetElementsByTagName([Ô]ano[Ô])
Dim ChNFeTagList As XmlNodeList = value.GetElementsByTagName([Ô]chNFe[Ô])
Dim CNPJTagList As XmlNodeList = value.GetElementsByTagName([Ô]CNPJ[Ô])
Dim CStatTagList As XmlNodeList = value.GetElementsByTagName([Ô]cStat[Ô])
Dim CUFTagList As XmlNodeList = value.GetElementsByTagName([Ô]cUF[Ô])
Dim DhRecbtoTagList As XmlNodeList = value.GetElementsByTagName([Ô]dhRecbto[Ô])
Dim DhRetornoTagList As XmlNodeList = value.GetElementsByTagName([Ô]dhRetorno[Ô])
Dim DigValTagList As XmlNodeList = value.GetElementsByTagName([Ô]digVal[Ô])
Dim ModTagList As XmlNodeList = value.GetElementsByTagName([Ô]mod[Ô])
Dim NNFFinTagList As XmlNodeList = value.GetElementsByTagName([Ô]nNFFin[Ô])
Dim NNFIniTagList As XmlNodeList = value.GetElementsByTagName([Ô]nNFIni[Ô])
Dim NProtTagList As XmlNodeList = value.GetElementsByTagName([Ô]nProt[Ô])
Dim NRecTagList As XmlNodeList = value.GetElementsByTagName([Ô]nRec[Ô])
Dim SerieTagList As XmlNodeList = value.GetElementsByTagName([Ô]serie[Ô])
Dim TMedTagList As XmlNodeList = value.GetElementsByTagName([Ô]tMed[Ô])
Dim TpAmbTagList As XmlNodeList = value.GetElementsByTagName([Ô]tpAmb[Ô])
Dim VerAplicTagList As XmlNodeList = value.GetElementsByTagName([Ô]verAplic[Ô])
Dim XMotivoTagList As XmlNodeList = value.GetElementsByTagName([Ô]xMotivo[Ô])
Dim XObsTagList As XmlNodeList = value.GetElementsByTagName([Ô]xObs[Ô])
If AnoTagList.Count > 0 Then
Me.vAno = AnoTagList(0).InnerText
Else
Me.vAno = [Ô][Ô]
End If
If ChNFeTagList.Count > 0 Then
Me.vChNFe = ChNFeTagList(0).InnerText
Else
Me.vChNFe = [Ô][Ô]
End If
If CNPJTagList.Count > 0 Then
Me.vCNPJ = CNPJTagList(0).InnerText
Else
Me.vCNPJ = [Ô][Ô]
End If
If CStatTagList.Count = 1 Then
Me.vCStat = CStatTagList(0).InnerText
Me.vCStatInicial = [Ô][Ô]
ElseIf CStatTagList.Count = 2 Then
Me.vCStat = CStatTagList(1).InnerText
Me.vCStatInicial = CStatTagList(0).InnerText
Else
Me.vCStat = [Ô][Ô]
Me.vCStatInicial = [Ô][Ô]
End If
If CUFTagList.Count > 0 Then
Me.vCUF = CUFTagList(0).InnerText
Else
Me.vCUF = [Ô][Ô]
End If
If DhRecbtoTagList.Count > 0 Then
Me.vDhRecbto = DhRecbtoTagList(0).InnerText
Else
Me.vDhRecbto = [Ô][Ô]
End If
If DhRetornoTagList.Count > 0 Then
Me.vDhRetorno = DhRetornoTagList(0).InnerText
Else
Me.vDhRetorno = [Ô][Ô]
End If
If DigValTagList.Count > 0 Then
Me.vDigVal = DigValTagList(0).InnerText
Else
Me.vDigVal = [Ô][Ô]
End If
If ModTagList.Count > 0 Then
Me.vMod = ModTagList(0).InnerText
Else
Me.vMod = [Ô][Ô]
End If
If NNFFinTagList.Count > 0 Then
Me.vNNFFin = NNFFinTagList(0).InnerText
Else
Me.vNNFFin = [Ô][Ô]
End If
If NNFIniTagList.Count > 0 Then
Me.vNNFIni = NNFIniTagList(0).InnerText
Else
Me.vNNFIni = [Ô][Ô]
End If
If NProtTagList.Count > 0 Then
Me.vNProt = NProtTagList(0).InnerText
Else
Me.vNProt = [Ô][Ô]
End If
If NRecTagList.Count > 0 Then
Me.vNRec = NRecTagList(0).InnerText
Else
Me.vNRec = [Ô][Ô]
End If
If SerieTagList.Count > 0 Then
Me.vSerie = SerieTagList(0).InnerText
Else
Me.vSerie = [Ô][Ô]
End If
If TMedTagList.Count > 0 Then
Me.vTMed = TMedTagList(0).InnerText
Else
Me.vTMed = [Ô][Ô]
End If
If TpAmbTagList.Count = 1 Then
Me.vTpAmb = TpAmbTagList(0).InnerText
Me.vTpAmbInicial = [Ô][Ô]
ElseIf TpAmbTagList.Count = 2 Then
Me.vTpAmb = TpAmbTagList(1).InnerText
Me.vTpAmbInicial = TpAmbTagList(0).InnerText
Else
Me.vTpAmb = [Ô][Ô]
Me.vTpAmbInicial = [Ô][Ô]
End If
If VerAplicTagList.Count = 1 Then
Me.vVerAplic = VerAplicTagList(0).InnerText
Me.vVerAplicInicial = [Ô][Ô]
ElseIf VerAplicTagList.Count = 2 Then
Me.vVerAplic = VerAplicTagList(1).InnerText
Me.vVerAplicInicial = VerAplicTagList(0).InnerText
Else
Me.vVerAplic = [Ô][Ô]
Me.vVerAplicInicial = [Ô][Ô]
End If
If XMotivoTagList.Count = 1 Then
Me.vXMotivo = XMotivoTagList(0).InnerText
Me.vXMotivoInicial = [Ô][Ô]
ElseIf XMotivoTagList.Count = 2 Then
Me.vXMotivo = XMotivoTagList(1).InnerText
Me.vXMotivoInicial = XMotivoTagList(0).InnerText
Else
Me.vXMotivo = [Ô][Ô]
Me.vXMotivoInicial = [Ô][Ô]
End If
If XObsTagList.Count > 0 Then
Me.vXObs = XObsTagList(0).InnerText
Else
Me.vXObs = [Ô][Ô]
End If
End Set
End Property
Public ReadOnly Property RESPOSTAWEBSERVICEXML() As String
Get
Return Me.vWebServiceXMLResponse
End Get
End Property
Public ReadOnly Property RESPANO()
Get
Return Me.vAno
End Get
End Property
Public ReadOnly Property RESPCHNFE()
Get
Return Me.vChNFe
End Get
End Property
Public ReadOnly Property RESPCNPJ()
Get
Return Me.vCNPJ
End Get
End Property
Public ReadOnly Property RESPCODIGOMENSAGEM()
Get
Return Me.vCStat
End Get
End Property
Public ReadOnly Property RESPCODIGOMENSAGEMINICIAL()
Get
Return Me.vCStatInicial
End Get
End Property
Public ReadOnly Property RESPCODIGOUF()
Get
Return Me.vCUF
End Get
End Property
Public ReadOnly Property RESPDATAHORARECEBIMENTO()
Get
Return Me.vDhRecbto
End Get
End Property
Public ReadOnly Property RESPDHRETORNO()
Get
Return Me.vDhRetorno
End Get
End Property
Public ReadOnly Property RESPDIGVAL()
Get
Return Me.vDigVal
End Get
End Property
Public ReadOnly Property RESPMOD()
G
somente hoje consegui iniciar os testes na DLL.
Por enquanto verifiquei a primeira parte da geração e me surgiu algumas dúvidas:
Na tag [ô]ide[ô], os campos B12a, B13, B14, B15, B16, B17, B18 e B20 não podem ser informados. Sei que esses campos devem ser utilzados apenas quando uma outra nota fiscal for referenciada, mas se não colocarmos isso na DLL ficamos restritos caso haja necessidade de utilizarmos esse recurso.
Agora acredito ter encontra um problema, mas como não tenho acesso ao fonte da DLL não sei se estou passando as informações de forma incorreta (é possivel postar o fonte da DLL?), mas segue abaixo o código que estou usando e parte do arquivo que ele está gerando:
Citação:x = xml.Looze_ChaveNFE([Ô]41[Ô], [Ô]15/05/2009[Ô], [Ô]96845896000189[Ô], [Ô]55[Ô], [Ô]1[Ô], [Ô]10[Ô], [Ô]dfdgfdDDD[Ô])
Call xml.Looze_Cabecalho([Ô]1.10[Ô], x)
x = xml.Looze_IDNFE([Ô]41[Ô], [Ô]9999[Ô], [Ô]vendas[Ô], [Ô]1[Ô], [Ô]55[Ô], [Ô]1[Ô], [Ô]10[Ô], [Ô]15/05/2009[Ô], [Ô]15/05/2009[Ô], [Ô]1[Ô], [Ô]4120903[Ô], [Ô]1[Ô], [Ô]1[Ô], [Ô]2[Ô], [Ô]3[Ô], [Ô]3[Ô], [Ô]TESTE 1.2.3[Ô], [Ô]96845896000189[Ô], [Ô]ddd[Ô])
Call xml.Looze_Emitente([Ô]01166372000155[Ô], [Ô]WRWRWQRW SYSTEMAS[Ô], [Ô]PROGma NET[Ô], [Ô]688134332111[Ô], [Ô]320203032[Ô], [Ô]46546[Ô], [Ô]13203[Ô], [Ô]RUA DE TESTE AJE DO MARANHAO[Ô], [Ô]999[Ô], [Ô]COMPLEMNTO DA NOTA[Ô], [Ô]BAIRRO DA NOTA[Ô], [Ô]669[Ô], [Ô]NOME DO MUNICIPIO[Ô], [Ô]UF[Ô], [Ô]13845132[Ô], [Ô]1058[Ô], [Ô]BRASIL[Ô], [Ô]019915915[Ô])
como resultado tenho o seguinte:
Citação:...
<infNFe Id=[Ô]NFe4105099684589600018955001100000000060[Ô] versao=[Ô]1.10[Ô]>
<ide>
<cUF>41</cUF>
<cNF>9999</cNF>
<natOp>vendas</natOp>
<indPag>1</indPag>
<mod>55</mod>
<serie>001</serie>
<nNF>000000010</nNF>
<dEmi>15/5/2009</dEmi>
<dSaiEnt>15/5/2009</dSaiEnt>
<tpNF>1</tpNF>
<cMunFG>4120903</cMunFG>
<tpImp>1</tpImp>
<tpEmis>1</tpEmis>
<cDV>0</cDV>
<tpAmb>2</tpAmb>
<finNFe>3</finNFe>
<procEmi>3</procEmi>
<verProc>TESTE 1.2.3</verProc>
</ide>
...
Temos alguns [Ô]problemas[Ô] (posso estar fazendo algo incorreto, se estiver por favor me avise):
- na chave de acesso a nota não está sendo formatada em 9 digÃtos, eu poderia solucionar o problema informando em 9 digÃtos, mas na função abaixo a formatação é tratada;
- note que estou passando na função Looze_IDNFE o [ô]cNF[ô] 9999 , porém na chave de acesso o valor correspondente a esse campo está como [ô]6[ô] formatado em 9 digÃtos.
O calculo do digito verificador parece estar sendo realizado com o valor passado pela função e não com o valor que está no arquivo.
Fiz o calculo com a chave [ô]4105099684589600018955001000000010000000006[ô] e o resultado do digito seria [ô]3[ô].
Já o calculo com a chave [ô]4105099684589600018955001000000010000009999[ô] o resultado seria o [ô]0[ô] que está sendo apresentado.
Formatei o campo da nota para poder testar o calculo, a formatação do mesmo não irá fazer diferenca na hora de calcular.
Public Function Calculo_DV11(strNumero As String) As String
[ô]declara as variáveis
Dim intcontador, intnumero, intTotalNumero, intMultiplicador, intResto As Integer
[ô] se nao for um valor numerico sai da função
If Not IsNumeric(strNumero) Then
Calculo_DV11 = [Ô][Ô]
Exit Function
End If
[ô]inicia o multiplicador
intMultiplicador = 9
[ô]pega cada caracter do numero a partir da direita
For intcontador = Len(strNumero) To 1 Step -1
[ô]extrai o caracter e multiplica prlo multiplicador
intnumero = Val(Mid(strNumero, intcontador, 1)) * intMultiplicador
[ô]soma o resultado para totalização
intTotalNumero = intTotalNumero + intnumero
[ô]se o multiplicador for maior que 2 decrementa-o caso contrario atribuir valor padrao original
intMultiplicador = IIf(intMultiplicador > 2, intMultiplicador - 1, 9)
Next
[ô]calcula o resto da divisao do total por 11
intResto = intTotalNumero Mod 11
[ô]verifica as exceções ( 0 -> DV=0 10 -> DV=X (para o BB) e retorna o DV
Select Case intResto
Case 0
Calculo_DV11 = [Ô]0[Ô]
Case 10
Calculo_DV11 = [Ô]0[Ô]
Case Else
Calculo_DV11 = Trim(Str(intResto))
End Select
End Function
Public Function Looze_ChaveNFE(Optional codUF As String, Optional DtEmissao As String, _
Optional CNPJ As String, Optional Modelo As String, Optional Serie As String, _
Optional NumeroNF As String, Optional Demo As String) As String
Dim Chave As String
Dim Digito As String
Dim CodNumerico As String
DtEmissao = Mid(DtEmissao, 7, 2) & Mid(DtEmissao, 4, 2) [ô]Format(DtEmissao, [Ô]MMYY[Ô])
CNPJ = SoNumero(CNPJ)
If VCNPJ_CPF(CNPJ) = False Then
MsgBox [Ô]CNPJ/CPF INVÃLIDO, não será possÃvel iniciar a chave.[Ô], vbCritical, [Ô]Erro Fatal.[Ô]
Exit Function
blErroFatal = True
End If
Modelo = Format(Modelo, [Ô]00[Ô])
Serie = Format(Serie, [Ô]000[Ô])
NumeroNF = Format(NumeroNF, [Ô]000000000[Ô])
CodNumerico = Format((Rnd(NumeroNF) * Val(9)), [Ô]000000000[Ô])
Chave = Trim(codUF & DtEmissao & CNPJ & Modelo & Serie & NumeroNF & CodNumerico)
Digito = Calculo_DV11(Chave)
Looze_ChaveNFE = Chave & Digito
If Len(Looze_ChaveNFE) <> 44 Then MsgBox [Ô]Erro ao gerar a chave de acesso.[Ô], vbCritical, [Ô]PROGma[Ô]
End Function
Public Function Looze_Digito(Optional Chave As String) As String
Looze_Digito = Calculo_DV11(Chave)
End Function
verifiquei a função e o problema está na forma como você está calculando. Eu alterei o código para gerar o valor correto.
Conforme escrito no manual:
Citação:O dÃgito verificador da chave de acesso da NF-e é baseado em um cálculo do
módulo 11. O módulo 11 de um número é calculado multiplicando-se cada algarismo pela
seqüência de multiplicadores 2,3,4,5,6,7,8,9,2,3, ... posicionados da direita para a esquerda.
Ou seja, deve-se pegar o ultimo numero da chave de acesso e multiplicar por 2, depois o proximo número da chave e multiplicar por 3, e assim por diante. Segue código alterado:
Public Function Calculo_DV11(strNumero As String) As String
[ô]declara as variáveis
Dim intcontador, intnumero, intTotalNumero, intMultiplicador, intResto As Integer
[ô] se nao for um valor numerico sai da função
If Not IsNumeric(strNumero) Then
Calculo_DV11 = [Ô][Ô]
Exit Function
End If
[ô]inicia o multiplicador com 2
intMultiplicador = 2
intTotalNumero = 0
[ô]pega cada caracter do numero a partir da direita
For intcontador = Len(strNumero) To 1 Step -1
[ô]extrai o caracter e multiplica prlo multiplicador
intnumero = Val(Mid(strNumero, intcontador, 1)) * intMultiplicador
[ô]soma o resultado para totalização
intTotalNumero = intTotalNumero + intnumero
[ô]se o multiplicador for maior ou igual a 2 atribui valor padrão, caso contrario incrementa
intMultiplicador = IIf(intMultiplicador >= 9, 2, intMultiplicador + 1)
Next
[ô]calcula o resto da divisao do total por 11
intResto = intTotalNumero Mod 11
[ô]verifica as exceções ( 0 -> DV=0 10 -> DV=X (para o BB) e retorna o DV
Select Case intResto
Case 0
Calculo_DV11 = [Ô]0[Ô]
Case 1
Calculo_DV11 = [Ô]0[Ô]
Case Else
Calculo_DV11 = Trim(Str(11 - intResto))
End Select
End Function
Agora vou verificar a proxima rotina e ver o que está sendo realizado. Acabei de chegar do almoço e não tive tempo de verificar as duas.
Looze,
note que você também não realizava o calculo: [ô]11 - resto da divisão[ô]. E que o [ô]select case[ô] precisou ser alterado.
RETORNO DA SEFAZ.
<?xml version=[Ô]1.0[Ô] encoding=[Ô]UTF-8[Ô]?><retConsReciNFe xmlns=[Ô]http://www.portalfiscal.inf.br/nfe[Ô] versao=[Ô]1.10[Ô]><tpAmb>2</tpAmb><verAplic>SP_NFE_PL_005d</verAplic><nRec>350000009788404</nRec><cStat>104</cStat><xMotivo>Lote processado</xMotivo><cUF>35</cUF><protNFe versao=[Ô]1.10[Ô]><infProt><tpAmb>2</tpAmb><verAplic>SP_NFE_PL_005d</verAplic><chNFe>35200510810925000151550010000409030000000066</chNFe><dhRecbto>2009-08-31T16:10:54</dhRecbto><digVal>UIhxQ/d8uuFvXQHnQRqUczXlGOM=</digVal><cStat>227</cStat><xMotivo>Rejeição: Erro na Chave de Acesso - Campo ID</xMotivo></infProt></protNFe></retConsReciNFe>
Onde esta errado na geração na chave?
eu corrigi o problema na geração do digito verificador, agora corrigi o problema na hora de gerar a chave:
Public Function Looze_ChaveNFE(Optional codUF As String, Optional CodNumerico As String, Optional DtEmissao As String, _
Optional CNPJ As String, Optional Modelo As String, Optional Serie As String, _
Optional NumeroNF As String, Optional Demo As String) As String
Dim Chave As String
Dim Digito As String
[ô]DtEmissao = Mid(DtEmissao, 7, 2) & Mid(DtEmissao, 4, 2) [ô]Format(DtEmissao, [Ô]MMYY[Ô]) // alterei para que o sistema trate a data passada em qualquer formato
DtEmissao = Format(CDate(DtEmissao), [Ô]MMYY[Ô]) [ô]Format(DtEmissao, [Ô]MMYY[Ô])
CNPJ = SoNumero(CNPJ)
If VCNPJ_CPF(CNPJ) = False Then
MsgBox [Ô]CNPJ/CPF INVÃLIDO, não será possÃvel iniciar a chave.[Ô], vbCritical, [Ô]Erro Fatal.[Ô]
Exit Function
blErroFatal = True
End If
Modelo = Format(Modelo, [Ô]00[Ô])
Serie = Format(Serie, [Ô]000[Ô])
NumeroNF = Format(NumeroNF, [Ô]000000000[Ô])
[ô]CodNumerico = Format((Rnd(NumeroNF) * Val(9)), [Ô]000000000[Ô]) // Deve ser igual ao informado na função Looze_IDNFE
CodNumerico = Format(CodNumerico, [Ô]000000000[Ô])
Chave = Trim(codUF & DtEmissao & CNPJ & Modelo & Serie & NumeroNF & CodNumerico)
Digito = Calculo_DV11(Chave)
Looze_ChaveNFE = Chave & Digito
If Len(Looze_ChaveNFE) <> 44 Then MsgBox [Ô]Erro ao gerar a chave de acesso.[Ô], vbCritical, [Ô]PROGma[Ô]
End Function
Pode tentar gerar que agora irá funcionar. Apenas se atente a passar o novo campo CodNumerico para essa função.
Qualquer dúvida no código me pergunte.
Citação:TIGER escreveu:
ow galera pra quem tiver dificuldade com os web services da NFe
estou postando um pequeno exemplo de como comunicar e obter retorno do Web service !
[txt-size=2] [/txt-size]
poderiamos todos nos ajudar TIGER , sua iniciativa foi boa nos ensinando como consumir web services de uma maneira facil e intuitiva com o .NET o LOOZE e mais uma equipe de programadores estao disponiveiz em desenvolver uma ferramenta pra facilitar nossa vida.. se puder disponibilizar mais fontes com as outras rotinas importantes pro sefaz poderiamos fechar logo o projeto e matar a charada.. ah... não sei se te interessa mais ja temos a DLL esta disponivel com o LOOZE ele abrira o fonte pra quem quizer OK. até.