Página 1 de 2

Desconto por ítem não imprime na danfe

Enviado: 24 Jun 2025 12:51
por malcarli
Boa tarde, anexo xml que tem desconto por ítem. Olhando a fonte do prg ze_sefaz_pdf_nfe, está previsto a impressão do desconto por ítem, mas o mesmo não está sendo impresso. Alguém poderia dar uma luz. Classe está atualizada na última versão. segue abaixo trecho onde está previsto a impressão.

Código: Selecionar todos


METHOD DefineColunasQuadroProdutos() CLASS hbNFeDaNFe

   LOCAL oElement, nItem, nCont, nColunaFinal, nTentativa

   ::ProcessaItens( ::cXml, 1 ) // precisa de ::aItem pra gerar o codeblock
   ::aLayout[ LAYOUT_CODIGO,     LAYOUT_TITULO1 ]   := "CÓDIGO"
   ::aLayout[ LAYOUT_CODIGO,     LAYOUT_CONTEUDO ]  := { || ::aItem[ "cProd" ] }
   ::aLayout[ LAYOUT_DESCRICAO,  LAYOUT_TITULO1 ]   := "DESCRIÇÃO DO PRODUTO / SERVIÇO"
   ::aLayout[ LAYOUT_DESCRICAO,  LAYOUT_CONTEUDO ]  := { || MemoLine( ::aItem[ "xProd" ], ::aLayout[ LAYOUT_DESCRICAO, LAYOUT_LARGURA ], 1 ) }
   ::aLayout[ LAYOUT_NCM,        LAYOUT_TITULO1 ]   := "NCM/SH"
   ::aLayout[ LAYOUT_NCM,        LAYOUT_CONTEUDO ]  := { || ::aItem[ "NCM" ] }
   ::aLayout[ LAYOUT_EAN,        LAYOUT_TITULO1 ]   := "EAN"
   ::aLayout[ LAYOUT_EAN,        LAYOUT_CONTEUDO ]  := { || ::aItem[ "cEAN" ] }
   ::aLayout[ LAYOUT_CST,        LAYOUT_TITULO1 ]   := "CST"
   ::aLayout[ LAYOUT_CST,        LAYOUT_TITULO2 ]   := "CSOSN"
   ::aLayout[ LAYOUT_CST,        LAYOUT_CONTEUDO ]  := { || ::aItemICMS[ "orig" ] + ::aItemICMS[ "CSOSN" ] + ::aItemICMS[ "CST" ] }
   ::aLayout[ LAYOUT_CFOP,       LAYOUT_TITULO1 ]   := "CFOP"
   ::aLayout[ LAYOUT_CFOP,       LAYOUT_CONTEUDO ]  := { || ::aItem[ "CFOP" ] }
   ::aLayout[ LAYOUT_UNIDADE,    LAYOUT_TITULO1 ]   := "UN"
   ::aLayout[ LAYOUT_UNIDADE,    LAYOUT_CONTEUDO ]  := { || ::aItem[ "uCom" ] }
   ::aLayout[ LAYOUT_QTD,        LAYOUT_TITULO1 ]   := "QTD"
   ::aLayout[ LAYOUT_QTD,        LAYOUT_CONTEUDO ]  := { || Alltrim( FormatNumber( Val( ::aItem[ "qCom" ] ), 15, ::aLayout[ LAYOUT_QTD, LAYOUT_DECIMAIS ] ) ) }
   ::aLayout[ LAYOUT_UNITARIO,   LAYOUT_TITULO1 ]   := "VALOR"
   ::aLayout[ LAYOUT_UNITARIO,   LAYOUT_TITULO2 ]   := "UNITÁRIO"
   ::aLayout[ LAYOUT_UNITARIO,   LAYOUT_CONTEUDO ]  := { || Alltrim( FormatNumber( Val( ::aItem[ "vUnCom" ] ), 15, ::aLayout[ LAYOUT_UNITARIO, LAYOUT_DECIMAIS ] ) ) }
   ::aLayout[ LAYOUT_TOTAL,      LAYOUT_TITULO1 ]   := "VALOR"
   ::aLayout[ LAYOUT_TOTAL,      LAYOUT_TITULO2 ]   := "TOTAL"
   ::aLayout[ LAYOUT_TOTAL,      LAYOUT_CONTEUDO ]  := { || Alltrim( FormatNumber( Val( ::aItem[ "vProd" ] ), 15, 2 ) ) }
   ::aLayout[ LAYOUT_DESCONTO,   LAYOUT_TITULO1 ]   := "VALOR"
   ::aLayout[ LAYOUT_DESCONTO,   LAYOUT_TITULO2 ]   := "DESCTO"
   ::aLayout[ LAYOUT_DESCONTO,   LAYOUT_CONTEUDO ]  := { || Alltrim( FormatNumber( Val( ::aItem[ "vDesc" ] ), 15, 2 ) ) }
   ::aLayout[ LAYOUT_ICMBAS,     LAYOUT_TITULO1 ]   := "B.CÁLC."
   ::aLayout[ LAYOUT_ICMBAS,     LAYOUT_TITULO2 ]   := "ICMS"
Att.

Marcelo A. L. Carli
Marília/SP
Capital Nacional do Alimento ®
https://malc-informatica.ueniweb.com
Insta: @malcarli25
Email / Skype: marceloalcarli@gmail.com

Desconto por ítem não imprime na danfe

Enviado: 24 Jun 2025 15:34
por JoséQuintas
Vou testar aqui.
É ativado com base em existir conteúdo.

Código: Selecionar todos

      IF Val( ::aItem[ "vDesc" ] ) > 0
         AtivaImprime( @::aLayout[ LAYOUT_DESCONTO, LAYOUT_IMPRIME ] )
      ENDIF

Desconto por ítem não imprime na danfe

Enviado: 24 Jun 2025 15:41
por JoséQuintas
Salvei XML na pasta sefaz/tests
rodei o test.exe
opção 1 de gerar danfe
O desconto está lá.
danfedesc.png

Desconto por ítem não imprime na danfe

Enviado: 24 Jun 2025 16:37
por JoséQuintas
Convém lembrar:
Se faltar espaço no Danfe, a coluna pode ser omitida.
Mas mesmo assim, aqui gerou normal.

Nesta parte, se não cabem as colunas, faz 5 testes, desativando uma coluna a cada teste

Código: Selecionar todos

      // MsgExclamation( "Largura descrição " + Str( ::aLayout[ LAYOUT_DESCRICAO, LAYOUT_LARGURAPDF ] ) )
      IF ::aLayout[ LAYOUT_DESCRICAO, LAYOUT_LARGURAPDF ] > 150
         EXIT
      ENDIF
      // Se não sobrar espaço suficiente pra descrição, desativa colunas
      DO CASE
      CASE nTentativa == 1 ; ::aLayout[ LAYOUT_EAN, LAYOUT_IMPRIME ]      := LAYOUT_NAOIMPRIME
      CASE nTentativa == 2 ; ::aLayout[ LAYOUT_SUBBAS, LAYOUT_IMPRIME ]   := LAYOUT_NAOIMPRIME
      CASE nTentativa == 3 ; ::aLayout[ LAYOUT_DESCONTO, LAYOUT_IMPRIME ] := LAYOUT_NAOIMPRIME
      CASE nTentativa == 4 ; ::aLayout[ LAYOUT_SUBVAL, LAYOUT_IMPRIME ]   := LAYOUT_NAOIMPRIME
      CASE nTentativa == 5
         ::aLayout[ LAYOUT_UN_TRIB, LAYOUT_IMPRIME ]    := LAYOUT_NAOIMPRIME
         ::aLayout[ LAYOUT_QTD_TRIB, LAYOUT_IMPRIME ]   := LAYOUT_NAOIMPRIME
         ::aLayout[ LAYOUT_VALOR_TRIB, LAYOUT_IMPRIME ] := LAYOUT_NAOIMPRIME
      ENDCASE
Apenas deixei anotado no fonte o que poderia agrupar, mas não agrupo
Ainda não pensei em lógica boa pra isso.

Código: Selecionar todos

// Pode juntar na mesma coluna:
// Código do produto e NCM
// CST e CFOP
// Qtde. e unidade
// valor unitário e desconto
// valor total e base icms
// base icms e base st
// icms e ipi
// aliquota icms e ipi

Desconto por ítem não imprime na danfe

Enviado: 24 Jun 2025 16:54
por malcarli
Sim, imprime no local, mas não por item em coluna conforme está no prg. deve ser por falta de espaço então

Desconto por ítem não imprime na danfe

Enviado: 24 Jun 2025 17:51
por JoséQuintas
Olhe a imagem que postei.
A coluna de desconto está lá.
Pelo menos com esse XML saiu.

Mas o código é gigante.
Pode pensar em rever isso talvez.
Poderia usar um código interno, numérico, mesmo mantendo o outro código pra uso geral.
E colocar o outro como adicional à descrição na NFE/Danfe.
É uma sugestão.
Talvez em outros produtos, com valores maiores não caiba.

Tem a opção de forçar a ativação.
Alguns ítens começam como LAYOUT_IMPRIMEXMLTEM, que é pra mostrar só se houver valor no XML.
Alterando pra LAYOUT_IMPRIME, vai forçar mostrar.

Se for isso mesmo, posso tentar trabalhar na opção de LAYOUT_IMPRIMESEGUNDA, que são aquelas pra usar duas linhas.
Mas parece ser liberar espaço pra ser desperdiçado.... sei lá....

Por falar nisso....
Tava pensando aqui....
Com a nova tributação, se entrar precisando mostrar as duas ao mesmo tempo... vamos ter que fabricar mais espaço....

Desconto por ítem não imprime na danfe

Enviado: 25 Jun 2025 09:11
por malcarli
Bom dia Mestre usando oDanfe := hbNfeDaGeral():New() dá certo, mas usando oDanfe:= hbnfeDanfe():new(), não mostra a coluna de desconto

Desconto por ítem não imprime na danfe

Enviado: 25 Jun 2025 12:17
por JoséQuintas
malcarli escreveu:Bom dia Mestre usando oDanfe := hbNfeDaGeral():New() dá certo, mas usando oDanfe:= hbnfeDanfe():new(), não mostra a coluna de desconto
Vixe, isso não deveria acontecer.
Vou verificar o que acontece com os defaults quando usa um ou outro.

Desconto por ítem não imprime na danfe

Enviado: 25 Jun 2025 12:23
por JoséQuintas
Veja que estranho:

Código: Selecionar todos

METHOD ToPDF( cXmlDocumento, cFilePDF, cXmlAuxiliar, oPDF, lEnd ) CLASS hbNFeDaGeral

   LOCAL oDanfe

   hb_Default( @lEnd, .T. )
   IF cXmlDocumento == NIL .OR. Empty( cXmlDocumento )
      RETURN "XML inválido"
   ENDIF
   IF Len( cXmlDocumento ) < 100
      IF File( cXmlDocumento )
         cXmlDocumento := MemoRead( cXmlDocumento )
      ENDIF
   ENDIF
   IF cXmlAuxiliar != NIL .AND. ! Empty( cXmlAuxiliar ) .AND. Len( cXmlAuxiliar ) < 100
      cXmlAuxiliar := MemoRead( cXmlAuxiliar )
   ENDIF
   DO CASE
   CASE "<infMDFe "   $ cXmlDocumento .AND. "<MDFe " $ cXmlDocumento                                                                 ; oDanfe := hbNFeDaMDFe():New()
   CASE "<infCte "    $ cXmlDocumento .AND. "<CTe "  $ cXmlDocumento                                                                 ; oDanfe := hbNFeDaCte():New()
   CASE "<infNFe "    $ cXmlDocumento .AND. "<NFe "  $ cXmlDocumento .AND. XmlNode( XmlNode( cXmlDocumento, "ide" ), "mod" ) == "55" ; oDanfe := hbNFeDaNFe():New()
   CASE "<infNFe "    $ cXmlDocumento .AND. "<NFe "  $ cXmlDocumento .AND. XmlNode( XmlNode( cXmlDocumento, "ide" ), "mod" ) == "65" ; oDanfe := hbNFeDaNFCe():New()
   CASE "<infNFe "    $ cXmlDocumento .AND. "<NFe>"  $ cXmlDocumento .AND. XmlNode( XmlNode( cXmlDocumento, "ide" ), "mod" ) == "55" ; oDanfe := hbNFeDaNFe():New()
   CASE "<infNFe "    $ cXmlDocumento .AND. "<NFe>"  $ cXmlDocumento .AND. XmlNode( XmlNode( cXmlDocumento, "ide" ), "mod" ) == "65" ; oDanfe := hbNFeDaNFCe():New()
   CASE "<infEvento " $ cXmlDocumento                                                                                                ; oDanfe := hbNFeDaEvento():New()
   OTHERWISE
      RETURN "XML inválido"
   ENDCASE
   oDanfe:lQuadroEntrega := ::lQuadroEntrega
   oDanfe:cLogoFile      := ::cLogoFile
   oDanfe:cDesenvolvedor := ::cDesenvolvedor

   IF ! lEnd
      oDanfe:ToPDF( cXmlDocumento, cFilePDF, cXmlAuxiliar, oPDF, lEnd )
      oPDF := oDanfe:oPDF
      RETURN oPDF
   ENDIF

   RETURN oDanfe:ToPDF( cXmlDocumento, cFilePDF, cXmlAuxiliar, oPDF, lEnd )
A ToPDF() do geral chama a ToPDF() da nota.
Não faz sentido ficar diferente.

Veja que é criada a classe pra daNFE, mesmo chamando daGERAL.
Só são repassados os parâmetros de quadro de entrega, logotipo e desenvolvedor , o resto é o default de daNFE.
O mesmo vale pra daNFE, daMDFE, daCTE, daNFCE, daEVENTO.
O daGERAL é apenas um intermediário que escolhe conforme o tipo de documento do XML.
Ele não afeta defaults da classe de pdf, a não ser esses 3 parâmetros que mostrei, e que dá pra confirmar nesse bloco de fonte que postei.

Sera que não está usando fonte diferente na hora de compilar ?
Lembrando que na linquedição entra o fonte da LIB que vier primeiro, caso tenha o fonte em mais de um lugar, ou o fonte do aplicativo.

Desconto por ítem não imprime na danfe

Enviado: 25 Jun 2025 12:45
por JoséQuintas
Lembrando também:
Só o mingw avisa de função duplicada, o blinker não.
Com blinker podem entrar funções repetidas e você nem fica sabendo.

No momento a possibilidade que me vém à cabeça é essa, de estar usando outro fonte.
Ou algum default diferente que não percebeu.

Se daGERAL funciona dentro do aplicativo, podemos descartar harupdf diferente da que está no harbour.

Desconto por ítem não imprime na danfe

Enviado: 25 Jun 2025 13:04
por JoséQuintas
Em todo caso fiz o teste:
testedanfe.png

Desconto por ítem não imprime na danfe

Enviado: 25 Jun 2025 13:08
por JoséQuintas
Pensando bem....
O daGERAL trata isso de passar ou nome ou conteúdo.
O daNFE não aceitou o nome, e não gerou nada.
Talvez o que viu tenha sido o PDF anterior, é outra possibilidade, caso tenha usado o nome.

O daGeral tem isto:

Código: Selecionar todos

   IF Len( cXmlDocumento ) < 100
      IF File( cXmlDocumento )
         cXmlDocumento := MemoRead( cXmlDocumento )
      ENDIF
   ENDIF
É o que a rotina usa pra decidir se é nome ou conteúdo.
Só tem no daGERAL.
Texto com menos de 100 letras, considera que é nome de arquivo

Já o daNFE não geraria nada com nome.

Desconto por ítem não imprime na danfe

Enviado: 25 Jun 2025 13:19
por JoséQuintas
Vou deixar todos iguais...
Acrescentando mesma checagem de nome:Len() < 100

Código: Selecionar todos

METHOD ToPDF( cXmlNFE, cFilePDF, cXmlCancel, oPDF, lEnd ) CLASS hbNFeDaNFe

   hb_Default( @lEnd, .T. )

   IF Empty( cXmlNFE )
      ::cRetorno := "XML sem conteúdo"
      RETURN ::cRetorno
   ENDIF
   IF Len( cXmlNFE ) < 100
      cXmlNFE := MemoRead( cXmlNFE )
   ENDIF
   IF ! Empty( cXmlCancel )
      IF Len( cXmlCancel ) < 100
         cXmlCancel := MemoRead( cXmlCancel )
      ENDIF
      ::cXmlCancel := cXmlCancel
   ENDIF
Vou alterar em todos pra ficarem iguais.
Tanto XML normal, quanto XML adicionais.

Desconto por ítem não imprime na danfe

Enviado: 25 Jun 2025 13:27
por JoséQuintas
Por pouco não fiz errado.... kkkkk

Código: Selecionar todos

METHOD ToPDF( cXmlNFE, cFilePDF, cXmlCancel, oPDF, lEnd ) CLASS hbNFeDaNFe

   hb_Default( @lEnd, .T. )

   IF Empty( cXmlNFE )
      ::cRetorno := "XML sem conteúdo"
      RETURN ::cRetorno
   ENDIF
   IF ! Empty( cXmlCancel )
      ::cXmlCancel := cXmlCancel
   ENDIF

   ::cXML   := cXmlNFE
   
   IF Len( ::cXml ) < 100
      ::cXml := Memoread( ::cXml )
   ENDIF
   IF ! Empty( ::cXmlCancel ) .AND. Len( ::cXmlCancel ) < 100
      ::cXmlCancel := MemoRead( ::cXmlCancel )
   ENDIF
Podem vir por parâmetro, mas pode ser que foram definidos nas variáveis ::cXml ou ::cXmlCancel
Melhor testar as variáveis ::cXML e ::cXmlCancel, pra valer pras duas situações.

Desconto por ítem não imprime na danfe

Enviado: 25 Jun 2025 13:55
por JoséQuintas
sefazclass.png
É só curiosidade.
Esse teste não é só da sefazclass.
Deixei aí a compilação de TUDO: harbour, hwgui, hmge, hmg3, oohg, sefazclass, boletoclass, pdfclass, e tudo mais.
Em mingw 7.3, 14.2 e 15.1

Em parte foi preguiça....
Deixei tudo junto, pra não precisar criar um workflow pra cada um.
Mas também porque sefazclass é o mais alterado.
O github desliga isso, se não for usado por 3 meses, e desligar seria problema, porque tem reaproveitamento de zips.