Ir para conteúdo
  • Cadastre-se

Elazar

Membros
  • Total de ítens

    45
  • Registro em

  • Última visita

  • Days Won

    6

Tudo que Elazar postou

  1. Fonte do ACBr de 14 de março de 2015??? isto? Se for atualize seus fontes... Testei isto esta semana, está tudo certo com a nota de referência... Mas acredito que pode não ser os fontes, veja sua lógica se talvez esteja atribuindo o número da nota referenciada no lugar correto.
  2. Acredito que a melhor forma seria apenas chamar o EnviarEvento, verificando se for True e em seguida testar se cada evento está entre um dos códigos aceitos... Pois EnviarEvento pode: Retornar True ao enviar evento de Cancelamento e o cancelamento não ter sido realizado (ex: existe cte ativa para a nota) Retornar True ao enviar evento de Carta de correção e o evento de CCe não ter sido registrado (ex: CCe para nota já cancelada... claro que o software não me deixaria fazer isto normalmente, fiz uns testes só para analisar as respostas). FEvento.InfEvento.cOrgao := FCodigoUF; FEvento.InfEvento.CNPJ := FCNPJ; FEvento.InfEvento.tpAmb := FOnwer.ACBr.Configuracoes.WebServices.Ambiente; FEvento.InfEvento.chNFe := Chave; FEvento.InfEvento.nSeqEvento := Sequencia; FEvento.InfEvento.dhEvento := Now; case FEventoTipo of nfevCartaCorrecao : begin FEvento.InfEvento.tpEvento := teCCe; FEvento.InfEvento.detEvento.xCorrecao := Motivo; FEvento.InfEvento.detEvento.xCondUso := ''; end; nfevCancelamento : begin FEvento.InfEvento.tpEvento := teCancelamento; FEvento.InfEvento.detEvento.xJust := Motivo; FEvento.InfEvento.detEvento.nProt := NotaProtocolo; end; end; Result := FOnwer.ACBr.EnviarEvento(1); Result := Result and (FEvento.RetInfEvento.cStat in [128,135,136,155]); //#rever 155 if Result then begin FStatus := FEvento.RetInfEvento.cStat; FProtocolo := FEvento.RetInfEvento.nProt; FMotivo := FEvento.RetInfEvento.xMotivo; FData := FEvento.RetInfEvento.dhRegEvento; FHora := FEvento.RetInfEvento.dhRegEvento; end else begin FFalha := Format('%d: %s', [FEvento.RetInfEvento.cStat, FEvento.RetInfEvento.xMotivo]); end;
  3. Olá, boa tarde, gostaria de confirmar o comportamento da função EnviarEvento quanto as possíveis respostas Temos que: function TNFeEnvEvento.TratarResposta: Boolean; begin ... Result := (EventoRetorno.cStat = 128) or (EventoRetorno.cStat = 135) or (EventoRetorno.cStat = 136) or (EventoRetorno.cStat = 155); Gostaria de confirmar que se mesmo um evento for processado e rejeitado pelo sefaz a função deveria retornar True? Entendo que pode ser enviado um lote de eventos, como vocês estão tratando atualmente isto? validando o cStat um por um? Exemplo: Cancele uma nota; Faça uma CCe para a mesma. A Função retorna True, mas o evento em si é rejeitado pelo sefaz. Para o caso de um Nota + CTe seguida de um cancelamento, retornará True também? (mesmo o evento de cancelamento ter falhado)? (Não consegui testar isto)
  4. Elazar

    Schema Evento CCe

    Olá, boa noite. Mais alguém está enfrentando este problema com a CCe? Trata-se de uma falha de validação do schema, com o seguinte erro: leiauteEvento_v1.00.xsd#/schema/complexType[2][@name = 'TRetEvento']/sequence[1]/element[1][@name = 'infEvento']/complexType[1]/sequence[1]/element[3][@name = 'cOrgao'] Undeclared XSD type : '{http://www.portalfiscal.inf.br/nfe}TCOrgaoIBGE'
  5. Correção para a copia das dlls para a %system% ocorrer. Correção da função que faz o registro das dlls, pois as msxml não são de registrar. ACBrNFeConfiguracoes.pas
  6. Olá, bom dia. Deixo uma contribuição para os fontes ACBr Inclusão de funcionalidade para registro "automático" de dlls no sistema do cliente. Adicionado em ACBrNFeConfiguracoes.TCertificadosConf dois novos metodos que juntos ficam responsáveis de copiar os arquivos capicom.dll, msxml5.dll, msxml5r.dll para a pasta de sistema do windows e também realizar o registro das mesmas (tal como é feito com o regsvr32). Classe TCertificadosConf GetRegistroCapicom : Boolean; GetIsAdmin : Boolean; GetRegistroCapicom Realiza o registro das dlls junto ao windows retornando True se caso as mesmas estão registradas (e seja possível acessar os certificados); Logo se as dlls forem ou estiverem registradas o Erro Classe Não Registrada não sera exibido e permitira a seleção do certificado. Para que este processo seja possível o seu executável precisa estar sendo executado como Administrador (não é o mesmo que estar no grupo de administrador) Procedimento faz distinção de sistema 64x32bits. GetIsAdmin Retorna verdadeiro caso seu sistema esteja sendo executado como administrador. Esta função foi copiada da internet, testei em Windows10, 8, 7 Server 2012, Server 2008. Agradeço se reportarem o funcionamento (ou não) em outros ambientes. Sobre as dlls. A função preve a distribuição das mesmas em dois locais junto com seu aplicativo. %seu aplicativo%\capicom.dll %seu aplicativo%\msxml5.dll %seu aplicativo%\msxml5r.dll e %seu aplicativo%\dll\df\capicom.dll %seu aplicativo%\dll\df\msxml5.dll %seu aplicativo%\dll\df\msxml5r.dll Elas serão copiadas para as pastas de sistema do windows, seja em 64 ou 32bits (syswow64, system32) . Utilizei código que funcione na versão mais antiga do delphi que tive acesso, no caso o D2009 agradeço se confirmarem funcionamento em versões mais novas. Exemplo de uso -Use GetIsAdmin para verificar se está como administrador, caso positivo chame GetRegistroCapicom -Exibir imagem/informativo solicitando execução como administrativo (o que utilizei por aqui). -Testar registro da capicom para habilitar autorização de documentos fiscais. Unit está atualizada com o trunk de hoje de manhã. ACBrNFeConfiguracoes.pas
  7. Olá, boa tarde. Tenho uma sugestão de melhoria quanto a questão de cor e espessura das bordas... nada mais que um pequeno ajuste cosmético, fica ai, caso houver possibilidade. ACBrNFeDANFERaveCB.pas ACBrDANFeCBRave.pas ACBrDANFeEventoRaveRetrato.pas ACBrDANFeCBRaveRetrato.pas ACBrDANFeCBRavePaisagem.pas
  8. Falha minha! ACBrNFeWebServices.pas
  9. Olá, bom dia; Sim e bastante, ainda não foi possível conferir tudo que precisava, mas acabei baixando novamente o trunk e atualizando as linhas do metodo TNFeEnvEvento.Executar: Boolean; Segue novamente! ACBrNFeWebServices.pas
  10. Feito! ACBrNFeWebServices.pas
  11. Na unit ACBrNFeWebServices.pas, seria interessante adicionar uma linha para o XML do retorno (destacado abaixo)... if FEvento.Evento.Items.InfEvento.chNFe = EventoRetorno.retEvento.Items[j].RetInfEvento.chNFe then begin wProc := TStringList.Create; wProc.Add('<?xml version="1.0" encoding="UTF-8" ?>'); wProc.Add('<procEventoNFe versao="' + GetVersaoNFe(FConfiguracoes.Geral.ModeloDF, FConfiguracoes.Geral.VersaoDF, LayNfeEvento) + '" xmlns="http://www.portalfiscal.inf.br/nfe">'); wProc.Add('<evento versao="' + GetVersaoNFe(FConfiguracoes.Geral.ModeloDF, FConfiguracoes.Geral.VersaoDF, LayNfeEvento) + '">'); Leitor.Arquivo := FDadosMSG; wProc.Add(UTF8Encode(Leitor.rExtrai(1, 'infEvento', '', i + 1))); // wProc.Add('</infEvento>'); wProc.Add('<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">'); Leitor.Arquivo := FDadosMSG; wProc.Add(UTF8Encode(Leitor.rExtrai(1, 'SignedInfo', '', i + 1))); // wProc.Add('</SignedInfo>'); Leitor.Arquivo := FDadosMSG; wProc.Add(UTF8Encode(Leitor.rExtrai(1, 'SignatureValue', '', i + 1))); // wProc.Add('</SignatureValue>'); Leitor.Arquivo := FDadosMSG; wProc.Add(UTF8Encode(Leitor.rExtrai(1, 'KeyInfo', '', i + 1))); // wProc.Add('</KeyInfo>'); wProc.Add('</Signature>'); wProc.Add('</evento>'); wProc.Add('<retEvento versao="' + GetVersaoNFe(FConfiguracoes.Geral.ModeloDF, FConfiguracoes.Geral.VersaoDF, LayNfeEvento) + '">'); Leitor.Arquivo := FRetWS; wProc.Add(UTF8Encode(Leitor.rExtrai(1, 'infEvento', '', j + 1))); // wProc.Add('</infEvento>'); wProc.Add('</retEvento>'); wProc.Add('</procEventoNFe>'); EventoRetorno.retEvento.Items[j].RetInfEvento.XML:=wProc.Text; // NomeArq := FEvento.Evento.Items.InfEvento.chNFe + // FEvento.Evento.Items.InfEvento.TipoEvento + // IntToStr(FEvento.Evento.Items.InfEvento.nSeqEvento) + // '-procEventoNFe.xml'; NomeArq := FEvento.Evento.Items.InfEvento.chNFe + FEvento.Evento.Items.InfEvento.TipoEvento + Format('%.2d', [FEvento.Evento.Items.InfEvento.nSeqEvento]) + '-procEventoNFe.xml'; { NomeArq := FEvento.Evento.Items.InfEvento.id + '-procEventoNFe.xml'; } FEvento.Evento.Items.RetInfEvento.nProt := EventoRetorno.retEvento.Items[j].RetInfEvento.nProt; FEvento.Evento.Items.RetInfEvento.dhRegEvento := EventoRetorno.retEvento.Items[j].RetInfEvento.dhRegEvento; FEvento.Evento.Items.RetInfEvento.cStat := EventoRetorno.retEvento.Items[j].RetInfEvento.cStat; FEvento.Evento.Items.RetInfEvento.xMotivo := EventoRetorno.retEvento.Items[j].RetInfEvento.xMotivo; FEvento.Evento.Items.RetInfEvento.XML := EventoRetorno.retEvento.Items[j].RetInfEvento.XML; if FConfiguracoes.Geral.Salvar then FConfiguracoes.Geral.Save(NomeArq, wProc.Text);
  12. Também houve o problema por aqui, mas foi intermitente, vezes acontecia, vezes não, ou várias vezes seguidas. Quanto a pergunta, você pode mudar algumas coisas, tente ver: ACBr.Configuracoes.WebServices.IntervaloTentativas ACBr.Configuracoes.WebServices.AguardarConsultaRet
  13. Excelente! Retiro o que disse sobre o código aleatório! Por isto que digo que é bom falar com pessoas inteligentes ...acho que tenho já algumas modificações anotadas pra fazer por aqui, estão incluídas as sugestões!
  14. Italo, boa noite, não se desculpe hehe; ainda mais se não faz sentido! Como havia duas funções, GerarChaveCTe e apenas GerarChave inicialmente havia imaginado que eu estava com algum problema nos fontes pois apenas a segunda era utilizada, o que não confirma dado sua resposta; O que houve é que dado um problema imaginei que era outro (com a chave) juntando com a existência dos dois métodos e ainda mais, sem saber da finalidade do primeiro (pra 1.03) me levou a modificar o mesmo e indicar como sugestão, pois, logo queria apenas frisar sobre a utilização de 9 digitos para o cCT ao invés dos 8 indicados no manual! Bem, confirmando, sim, está correto desta forma como vocês todos indicaram! Apenas uma ressalva quanto ao utilizar o cCT de forma randômica, pois se por algum motivo a chave for perdida não há meios descobrir a mesma, então de forma parcial a minha dica de utilizar o -1 para o cCT continua;
  15. Juliomar, Realmente não tinha pensado por este ponto de vista, por experiencia foi justamente este o motivo de perguntar. Mas acabei utilizando a outra opção (com o valor -1) que ele não preenche com zeros e sim faz um calculo com o numero do documento (ou seja é possível chegar ao valor da chave novamente se souber como foi feito internamente); Acredito que desta forma não fica simplesmente com zeros de forma fácil de ser reconhecida por qualquer um! Mark Apollo, Acabei de verificar e está correto como informei, no manual 1.04 onde tem a diferença de 1 digito (a menos) no campo cCT para deixar espaço para o tipo de emissão. Olhe na pagina 78, exatamente as duas ultimas linhas (continuando na 79) descrevem este fato; Logo a sugestão não está descartada.. hehe, ficou irrisória, vou manter por hora! De forma consolidada para a 1.04 a especificação diz (abaixo) ... mas claro que acredito que isto não é um problema! cUF - Código da UF do emitente do Documento Fiscal • AAMM - Ano e Mês de emissão do CT-e • CNPJ - CNPJ do emitente • mod - Modelo do Documento Fiscal • serie - Série do Documento Fiscal • nCT - Número do Documento Fiscal • tpEmis – Forma de emissão do CT-e 1 digito • cCT - Código Numérico que compõe a Chave de Acesso *8 digitos • cDV - Dígito Verificador da Chave de Acesso Resolução do problema Aproveito o post para explicar o que houve comigo, pois achei a solução. Ocorre que uso alguns procedimentos internos no fonte para evitar que acidentalmente eu, funcionários, colegas utilizem o sistema em modo de produção indevidamente, e isto mesmo que ocorreu, minha "trava alonsos" me pegou ; Logo tentava sempre autorizar em homologação, descobri ao ativar a opção para salvar os arquivos de resposta; Fica a dica pra quem pensar nas próprias caso já tenha enganado-se com os ambientes de produção/homologação: Use a diretiva {$IFOPT D+} (delphi debugger information no google), claro por si só não é o suficiente, invente as suas, a que me atrapalhou/salvou foi uma do IP (de dentro da empresa) ninguém autoriza nada de verdade! Galera; Obrigado pelas respostas
  16. Boa noite pessoal; Estava acompanhando alguns topicos em relação a CTe 2.0 entretanto não consegui localizar maiores informações referente as mesmas, em contrapartida estou enfrentando um pequeno problema durante a autorização de uma CTe; A quem interessar possa, minha sugestão é quanto ao GerarXml e GerarChaveCTe; Pra ser mais especifico foram 3 alterações (o motivo explico depois); 1) pcteCTeWV104.inc, linha 170 +- fiz uma pequena alteração para utilizar o metodo GerarChaveCte o qual fiz uma breve modificação também. ..... .... function TCTeW.GerarXml: boolean; var chave: AnsiString; Gerar: boolean; xProtCTe : String; begin chave := ''; { comentei if not GerarChave(Chave, CTe.ide.cUF, CTe.ide.cCT, StrToInt(CTe.ide.modelo), CTe.ide.serie, CTe.ide.nCT, StrToInt(TpEmisToStr(CTe.ide.tpEmis)), CTe.ide.dhEmi, CTe.emit.CNPJ) then} if not GerarChaveCTe(Chave, CTe.ide.cUF, CTe.ide.cCT, StrToInt(TpEmisToStr(CTe.ide.tpEmis)), StrToInt(CTe.ide.modelo), CTe.ide.serie, CTe.ide.nCT, CTe.ide.dhEmi, CTe.emit.CNPJ) then Gerador.wAlerta('#001', 'infCte', DSC_CHAVE, ERR_MSG_GERAR_CHAVE); ..... .... 2) Alteração em pcnNFeW function TNFeW.GerarXml: boolean; var chave: AnsiString; Gerar: boolean; xProtNFe : String; begin chave := ''; if NFe.infNFe.Versao >= 2 then begin FSchema := TsPL006; if not GerarChave(Chave, nfe.ide.cUF, nfe.ide.cNF, nfe.ide.modelo, nfe.ide.serie, nfe.ide.nNF, StrToInt(TpEmisToStr(nfe.ide.tpEmis)), nfe.ide.dEmi, nfe.emit.CNPJCPF) then Gerador.wAlerta('A01', 'infNFe', DSC_CHAVE, ERR_MSG_GERAR_CHAVE); end else begin FSchema := TsPL005c; if not GerarChaveCTe(chave, nfe.ide.cUF, nfe.ide.cNF, StrToInt(TpEmisToStr(nfe.ide.tpEmis)), nfe.ide.modelo, nfe.ide.serie, nfe.ide.nNF, nfe.ide.dEmi, nfe.emit.CNPJCPF) then Gerador.wAlerta('A01', 'infNFe', DSC_CHAVE, ERR_MSG_GERAR_CHAVE); end; 3) Modificação do GerarChaveCte, visando estabelecer da forma que consta no manual (ainda) 1.04 referente tpEmis – Forma de emissão do CT-e Unit: pcnAuxiliar function GerarChaveCTe(var chave: AnsiString; const codigoUF: integer; codigoNumerico: integer; TipoEmissao : Integer; const modelo, serie, numero: integer; const emissao: TDateTime; const CNPJ: string): boolean; var digito: integer; wAno, wMes, wDia: Word; begin result := true; try // Se o usuario informar 0; o código numerico sera gerado de maneira aleatória // while codigoNumerico = 0 do begin Randomize; codigoNumerico := Random(999999999); end; // se o usuario informar -1 o código numerico será gerado atravéz da função // GerarCódigoNumerico baseado no numero do documento fiscal. if codigoNumerico = -1 then codigoNumerico := GerarCodigoNumerico(Numero); // DecodeDate(emissao, wAno, wMes, wDia); chave := 'CTe' + IntToStrZero(codigoUF, 2) + Copy(FormatFloat('0000', wAno), 3, 2) + FormatFloat('00', wMes) + copy(SomenteNumeros(CNPJ) + '00000000000000', 1, 14) + IntToStrZero(modelo, 2) + IntToStrZero(serie, 3) + IntToStrZero(Numero, 9) + IntToStrZero(TipoEmissao, 1) + <------------ IntToStrZero(codigoNumerico, 8); <------------ GerarDigito(digito, chave); chave := chave + IntToStr(digito); except chave := ''; result := false; exit; end; end; Sugestão de preenchimento das tags CTe; .... ... FCTe.Ide.modelo := '57'; FCTe.Ide.serie := FSerie; FCte.Ide.cCT := -1; <<<<------------ informe -1 FCTe.Ide.nCT := FNumero; FCTe.Ide.dhEmi := dhEmissao; FCTe.Ide.tpImp := tiRetrato; ... ... Motivo; Hoje a tarde, depois de dias, inúmeros testes, e por necessidade houve a primeira tentativa de emissão de uma CTe em produção, resultado? o pior possivel: nenhum; Simplesmente não sei o que houve, agora tentando com o mesmo numero de CTe 1, Serie 1; Obtenho a seguinte mensagem de erro: 1->Rejeicao: Duplicidade de CT-e, com diferença na Chave de Acesso [chCTe:43100003741872000107570010000000011078888360][nRec:431000004474279] Estranho que consultando a chave citada mostra a mesma como homologação, mas a mensagem ocorre durante a tentativa de autorização em produção; Enfim; Vou estudar mais um pouco e aguardar as opiniões dos colegas, mas esgotadas as possibilidades mais um teste farei (com numero 2); As modificações sugeridas surgiram em virtude de a funcão anterior GerarChave utilizar o tal cCT por padrão para criar um numero randomico para os penultimos 9 digitos da Chave da CTe. O que em certo caso, de maneira prática vai impossibilitar a consulta da CTe (se já emitida), porque teria que ir 'testando' a chave até achar o numero; Por curiosidade (duvidas) Porque estes 8 digitos (cCT - Código Numérico que compõe a Chave de Acesso) na chave tem que ser "de certa forma" aleatórios e preenchidos? não pode ser zeros? só gostaria de entender os motivos... se ainda for relevante!
  17. OBS: a quem for usar, precisa trocar o tipo TNotaFiscalEventos para TpcnTpEvento, e fazer uma breve modificação no case!
  18. Olá, bom dia; Claro; Segue também uma classe genérica para fazer autorização dos eventos; (sugestões são bem vindas). TNotaFiscalEventosWebService = class(TObject) private FOnwer : TACBrNfe; FSequencia : Integer; FEvento : TNotaFiscalEventos; FChave : String; FMotivo : String; FCodigoUF : Integer; FCNPJ : String; FProtocolo : String; FData : TDateTime; public constructor Create(AOwner : TACBrNfe); destructor Destroy; override; property Sequencia : Integer read FSequencia write FSequencia; property Evento : TNotaFiscalEventos read FEvento write FEvento; property Motivo : String read FMotivo write FMotivo; property Chave : String read FChave write FChave; property CNPJ : String read FCNPJ write FCNPJ; property CodigoUF : Integer read FCodigoUF write FCodigoUF; property Protocolo : String read FProtocolo; property Data : TDateTime read FData; function Autorizar : Boolean; end; { TNotaFiscalEventosWebService } constructor TNotaFiscalEventosWebService.Create(AOwner: TNotaFiscalWebService); begin FOnwer := AOwner; end; destructor TNotaFiscalEventosWebService.Destroy; begin inherited Destroy; end; function TNotaFiscalEventosWebService.Autorizar: Boolean; var evEvento : TInfEventoCollectionItem; begin FOnwer.EventoNFe.Evento.Clear; evEvento := FOnwer.EventoNFe.Evento.Add; evEvento.InfEvento.cOrgao := FCodigoUF; evEvento.InfEvento.CNPJ := FCNPJ; evEvento.InfEvento.tpAmb := FOnwer.ACBr.Configuracoes.WebServices.Ambiente; evEvento.InfEvento.chNFe := Chave; evEvento.InfEvento.nSeqEvento := Sequencia; evEvento.InfEvento.dhEvento := Now; case Evento of nfevCartaCorrecao : begin evEvento.InfEvento.tpEvento := teCCe; evEvento.InfEvento.detEvento.xCorrecao := Motivo; evEvento.InfEvento.detEvento.xCondUso := ''; end; end; Result := ACBr.EnviarEventoNFe(1); if Result then begin FProtocolo := evEvento.RetInfEvento.nProt; FData := evEvento.RetInfEvento.dhRegEvento; end; ACBr.ImprimirEvento; ACBr.ImprimirEventoPDF; end; ACBrNFeWebServices.pas
  19. Pessoal; Já alguns dias tenho notado que os retornos das CCe estavam ficando com o numero de protocolo em branco, fui depurar um pouco o fonte e cheguei a conclusão de que as informações do protocolo e data de registro do evento não estão sendo preenchidas de acordo com o resultado. Bem, resumindo, fiz uma pequena modificação na unit ACBrNFeWebServices, linha 3615; ... if FEvento.Evento.Items.InfEvento.chNFe = EventoRetorno.retEvento.Items[j].RetInfEvento.chNFe then begin { as proximas 3 linhas copian o resultado do processamento de arquivo de retorno para as propriedades originais que criaram os eventos} FEvento.Evento.Items.RetInfEvento.nProt := EventoRetorno.retEvento.Items[j].RetInfEvento.nProt; FEvento.Evento.Items.RetInfEvento.dhRegEvento := EventoRetorno.retEvento.Items[j].RetInfEvento.dhRegEvento; FEvento.Evento.Items.RetInfEvento.cStat := EventoRetorno.retEvento.Items[j].RetInfEvento.cStat; wProc := TStringList.Create; Apenas a titulo de exemplo, segue print de como ficou o pdf da cce;
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.