Muitas empresas enviam o DANFE da NF-e em formato PDF para os clientes no mesmo e-mail no qual enviam o XML da NF-e. Então, o pessoal do departamento fiscal da sua empresa chega na sua mesa e fala "olha, eu também quero!".
Para que isso seja possível, acabamos desenvolvendo uma função no ECC que recebe a chave de acesso da NF-e e retorna o PDF do DANFE.
Da mesma forma, o mesmo usuário gostaria de poder visualizar o DANFE no monitor web do SAP NF-e. A SAP disponibilizou esta funcionalidade no SAP NF-e utilizando 2 formulários Adobe, que geram o PDF em runtime, mas estes não são exatamente iguais ao DANFE original gerado pelo ECC.
Este blog mostra como baixar o PDF do DANFE gerado pelo ECC no monitor do SAP NF-e, reutilizando a função criada originalmente para recuperar o PDF do DANFE para envio do PDF via e-mail.
Para permitir o download do PDF do DANFE original, gerado pelo ECC, irei desenvolver dois módulos de função no lado do ECC, ajustar o programa de impressão e criar um implicit enhancement point na classe que trata o evento de baixar o DANFE no lado do SAP NF-e.
No lado do ECC, alguns ajustes serão necessários no programa de impressão do DANFE para a gente consiga exportar o PDF do DANFE após a execução do programa de impressão. Isso foi coberto pelo excelente blog do fabio.purcinoaragao - Como gerar o DANFE em PDF , por isso não vou entrar nos detalhes da alteração do programa de impressão.
Criei uma função Z, que recebe o número do documento e retorna o arquivo do PDF, conforme abaixo:
FUNCTION Z_SD_NFE_GET_DANFE_PDF.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(I_DOCNUM) TYPE J_1BDOCNUM
*" EXPORTING
*" REFERENCE(ET_FILE) TYPE TLINE_T
*" REFERENCE(E_FILESIZE) TYPE INT4
*" EXCEPTIONS
*" DOCUMENT_NOT_FOUND
*" NFE_NOT_APPROVED
*" NFE_NOT_PRINTED
*" CONVERSION_EXCEPTION
*" PRINT_PROGRAM_ERROR
*"----------------------------------------------------------------------
TABLES: nast , tnapr.
TYPES: BEGIN OF ty_doc,
docnum LIKE j_1bnfdoc-docnum,
form LIKE j_1bnfdoc-form,
code LIKE j_1bnfe_active-code,
printd LIKE j_1bnfe_active-printd,
conting LIKE j_1bnfe_active-conting,
END OF ty_doc.
DATA: ls_doc TYPE ty_doc,
lv_subrc TYPE i VALUE 0,
lv_screen TYPE i VALUE 0,
lv_buf_id TYPE indx_srtfd.
SELECT SINGLE a~docnum a~form b~code b~printd b~conting
FROM j_1bnfdoc AS a
INNER JOIN j_1bnfe_active AS b
ON b~docnum = a~docnum
INTO ls_doc
WHERE a~docnum EQ i_docnum.
IF sy-subrc NE 0.
RAISE document_not_found.
ENDIF.
IF ls_doc-conting = abap_false.
IF ls_doc-code NE '100'.
RAISE nfe_not_approved.
ENDIF.
IF ls_doc-printd NE 'X'.
RAISE nfe_not_printed.
ENDIF.
ENDIF.
lv_buf_id = 'DANFE_OTF_' && ls_doc-docnum.
SELECT SINGLE * FROM tnapr INTO tnapr WHERE kschl = ls_doc-form.
nast-kappl = tnapr-kappl.
nast-OBJKY = ls_doc-docnum.
nast-kschl = tnapr-kschl.
nast-spras = 'P'.
nast-erdat = sy-datum.
nast-eruhr = sy-uzeit.
nast-nacha = 1.
nast-anzal = 1.
nast-vsztp = 1.
nast-ldest = 'LOCL'.
nast-nauto = 'X'.
PERFORM entry IN PROGRAM znfe_print_danfe USING lv_subrc lv_screen.
IF lv_subrc NE 0.
RAISE print_program_error.
ENDIF.
DATA: it_pdf TYPE TABLE OF itcoo.
DATA: it_otf TYPE tsfotf.
IMPORT e_parm = it_otf[] FROM SHARED BUFFER INDX(ST) ID lv_buf_id.
DELETE FROM SHARED BUFFER INDX(ST) ID lv_buf_id.
it_pdf[] = it_otf[].
CALL FUNCTION 'CONVERT_OTF'
EXPORTING
FORMAT = 'PDF'
MAX_LINEWIDTH = 132
IMPORTING
BIN_FILESIZE = e_filesize
TABLES
OTF = it_pdf
LINES = et_file
EXCEPTIONS
ERR_MAX_LINEWIDTH = 1
ERR_FORMAT = 2
ERR_CONV_NOT_POSSIBLE = 3
ERR_BAD_OTF = 4
OTHERS = 5.
IF sy-subrc NE 0.
RAISE conversion_exception.
ENDIF.
ENDFUNCTION.
Note que a função faz uso de um IMPORT FROM SHARED BUFFER. No meu programa de impressão eu faço o EXPORT, conforme abaixo:
Criei uma função Z, marcada como RFC Enabled, para recuperar os e-mails do parceiro (Comprador ou Transportador), assim como o PDF do DANFE, caso solicitado, conforme abaixo:
FUNCTION Z_SD_NFE_GET_B2B_DATA.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(IV_ACCESS_KEY) TYPE J_1B_NFE_ACCESS_KEY_DTEL44
*" VALUE(IV_SCENARIO) TYPE CHAR10
*" VALUE(IV_GET_DANFE) TYPE FLAG OPTIONAL
*" EXPORTING
*" VALUE(ET_COMM) TYPE ZNFE_COMMPARAM_T
*" VALUE(EV_DANFE) TYPE XSTRING
*"----------------------------------------------------------------------
DATA: lv_parvw TYPE j_1bparvw,
lv_parid TYPE j_1bparid,
lv_partyp TYPE j_1bpartyp,
lv_docnum TYPE j_1bdocnum,
lv_adrnr TYPE adrnr,
lt_email TYPE TABLE OF ad_smtpadr,
lt_file TYPE TLINE_T,
lv_filesize TYPE int4,
ls_comm TYPE znfe_commparam,
ls_key TYPE J_1B_NFE_ACCESS_KEY.
FIELD-SYMBOLS: <fs_mail> TYPE ad_smtpadr.
MOVE iv_access_key TO ls_key.
CASE iv_scenario.
WHEN 'BUYER'.
lv_parvw = 'AG'.
WHEN 'CARRIER'.
lv_parvw = 'SP'.
WHEN OTHERS.
RETURN.
ENDCASE.
SELECT SINGLE b~docnum b~parid b~partyp
INTO (lv_docnum, lv_parid, lv_partyp)
FROM j_1bnfe_active AS a
INNER JOIN j_1bnfnad AS b ON a~docnum = b~docnum
WHERE a~REGIO = ls_key-regio AND
a~NFYEAR = ls_key-NFYEAR AND
a~NFMONTH = ls_key-NFMONTH AND
a~STCD1 = ls_key-STCD1 AND
a~MODEL = ls_key-MODEL AND
a~SERIE = ls_key-SERIE AND
a~NFNUM9 = ls_key-NFNUM9 AND
a~DOCNUM9 = ls_key-DOCNUM9 AND
a~CDV = ls_key-cdv AND
b~parvw = lv_parvw.
IF sy-subrc NE 0.
RETURN.
ENDIF.
CASE lv_partyp.
WHEN 'C'.
SELECT SINGLE adrnr INTO lv_adrnr FROM kna1 WHERE kunnr = lv_parid.
WHEN 'V'.
SELECT SINGLE adrnr INTO lv_adrnr FROM lfa1 WHERE lifnr = lv_parid.
WHEN 'B'.
SELECT SINGLE adrnr INTO lv_adrnr FROM j_1bbranch
WHERE bukrs = lv_parid(4) AND branch = lv_parid+4.
ENDCASE.
SELECT a~smtp_addr
INTO TABLE lt_email
FROM ( adr6 AS a
INNER JOIN adrt AS t ON
a~addrnumber EQ t~addrnumber
AND a~consnumber EQ t~consnumber )
WHERE a~addrnumber EQ lv_adrnr
AND t~comm_type EQ 'INT'
AND t~remark EQ 'NFE'.
IF sy-subrc EQ 0.
LOOP AT lt_email ASSIGNING <fs_mail>.
ls_comm-type = 'MAIL'.
ls_comm-value = <fs_mail>.
APPEND ls_comm TO et_comm.
ENDLOOP.
ENDIF.
IF iv_get_danfe EQ abap_true.
CALL FUNCTION 'Z_SD_NFE_GET_DANFE_PDF'
EXPORTING
I_DOCNUM = lv_docnum
IMPORTING
ET_FILE = lt_file
E_FILESIZE = lv_filesize
EXCEPTIONS
DOCUMENT_NOT_FOUND = 1
NFE_NOT_APPROVED = 2
NFE_NOT_PRINTED = 3
CONVERSION_EXCEPTION = 4
PRINT_PROGRAM_ERROR = 5
OTHERS = 6.
DATA: lv_str TYPE string.
CONCATENATE LINES OF lt_file INTO lv_str.
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
TEXT = lv_str
ENCODING = '4102'
IMPORTING
BUFFER = ev_danfe
EXCEPTIONS
FAILED = 1
OTHERS = 2.
ENDIF.
ENDFUNCTION.
No lado do SAP NF-e, é necessário criar um implicit enhancement point na classe /XNFE/CL_NFE_OUT para desviar a lógica para efetuar o download do PDF para o ECC via RFC e não via formulário standard do SAP NF-e.
Abra a classe /XNFE/CL_NFE_OUT na SE24, vá no menu Edit -> Enhancement Operations -> Show Implicit Enhancement Options.
Irá aparecer uma linha nova, logo abaixo da linha que declara o método. Clique nesta linha e vá no menu Edit -> Enhancement Operations -> Create Implementation:
Selecione Data Declaration como método de Enhancement.
No código, coloque o trecho abaixo:
DATA: lv_danfe_file TYPE string,
lv_logsys TYPE logsys,
lv_rfcdest TYPE bdbapidst,
lv_danfe TYPE xstring.
"get filename
concatenate /xnfe/if_wd_constants=>cv_xml_file_front_nfe
me->mv_id /xnfe/if_wd_constants=>cv_pdf_extension into lv_danfe_file.
"Read Logical System
SELECT SINGLE logsys
INTO lv_logsys
FROM /xnfe/outnfehd
WHERE guid = me->mv_guid.
IF sy-subrc EQ 0.
"Read RFC Destination
CALL FUNCTION '/XNFE/READ_RFC_DESTINATION'
EXPORTING
iv_logsys = lv_logsys
IMPORTING
ev_rfcdest = lv_rfcdest
EXCEPTIONS
no_dest_found = 1.
"Get NF-e DANFE`s PDF
IF sy-subrc EQ 0.
CALL FUNCTION 'Z_SD_NFE_GET_B2B_DATA'
DESTINATION lv_rfcdest
EXPORTING
iv_access_key = me->mv_id
iv_scenario = 'BUYER'
iv_get_danfe = abap_true
IMPORTING
ev_danfe = lv_danfe.
"open download dialog and show PDF
cl_wd_runtime_services=>attach_file_to_response(
i_filename = lv_danfe_file
i_content = lv_danfe
i_mime_type = /xnfe/if_wd_constants=>cv_pfd_mimetype
i_in_new_window = abap_true
i_inplace = abap_false ).
ENDIF.
ENDIF.
RETURN.
Salve e ative o código.
Efetue um teste e veja que agora o PDF baixado via monitor NF-e é o mesmo vindo do ECC e não mais o gerado pelo GRC. Caso necessário, você pode implementar uma lógica no seu programa de impressão para que seja impressa uma marca-d'água indicando que o DANFE é uma cópia.
Nota: Gostou do editor ABAP com fundo preto e cara de terminal *nix? Veja como fazer no seu SAP Logon seguindo o blog Make your ABAP editor go dark | Bruno Lucattelli dobruno.lucattelli .
[]'s
JN
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.