PDA

Ver la Versión Completa : Convertir factura a PDF y anexarla al documento VBRK


SAPLH
28/05/10, 08:55:06
A quien pueda ayudarme:

Como parte del proceso de facturación, creo un documento PDF con una copia de la factura (generada desde smartofrms), el siguiente paso es anexarlo al documento factura (VBRK).

En principio, ambos pasos funcionan tengo un PDF correcto donde he pedido y un anexo en la lista de anexos (GOS) de la factura, pero al pulsar en el GOS para abrirlo con el ACROBAT se produce un error porque busca un archivo PDF corrupto y con un nombre parecido en c:\.. ..sapworkdir !!!.

Esta es la parte del código que genera el PDF en local:
_______________________________________________________
FORM convert_to_pdf.

* Convert to PDF ...

CALL FUNCTION 'CONVERT_OTF'
EXPORTING
format = 'PDF'
IMPORTING
bin_filesize = lv_doc_size
TABLES
otf = ls_job_info-otfdata
lines = lines
EXCEPTIONS
err_conv_not_possible = 1
err_bad_otf = 2.

* Download to your PC ...

CONCATENATE 'C:\TEMP\' vbeln '.pdf' INTO file.

CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
bin_filesize = lv_doc_size
filename = file
filetype = 'BIN'
TABLES
data_tab = lines[].

IF sy-subrc = 0.
MESSAGE 'Descarga completada normalmente' TYPE 'S'.
ENDIF.

ENDFORM. "convert_to_pdf
_______________________________________________________


Esta es la parte del código anexa el PDF a la factura:

_______________________________________________________
FORM crear_anexo.

* Include for BO macros
INCLUDE : <cntn01>.
* Load class.
CLASS cl_binary_relation DEFINITION LOAD.
CLASS cl_obl_object DEFINITION LOAD.

TYPES: BEGIN OF ty_message_key,
foltp TYPE so_fol_tp,
folyr TYPE so_fol_yr,
folno TYPE so_fol_no,
doctp TYPE so_doc_tp,
docyr TYPE so_doc_yr,
docno TYPE so_doc_no,
fortp TYPE so_for_tp,
foryr TYPE so_for_yr,
forno TYPE so_for_no,
END OF ty_message_key.

DATA : lv_message_key TYPE ty_message_key.
DATA : lo_message TYPE swc_object.
DATA : p_reltyp LIKE mdoblrel-reltype.
DATA : lv_title TYPE string.

* First derive the Attachment's ( MESSAGE ) document type.
p_reltyp = 'ATTA'.
CONCATENATE 'Copia factura nº: ' vbeln INTO lv_title SEPARATED BY space.

* Create an initial instance of BO 'MESSAGE' - to call the
* instance-independent method 'Create'.
swc_create_object lo_message 'MESSAGE' lv_message_key.

* define container to pass the parameter values to the method call
* in next step.
swc_container lt_message_container.

* Populate container with parameters for method
swc_set_element lt_message_container 'DOCUMENTTITLE' vbeln.
swc_set_element lt_message_container 'DOCUMENTLANGU' 'S'.
swc_set_element lt_message_container 'NO_DIALOG' 'X'.
swc_set_element lt_message_container 'DOCUMENTPATH' 'C:\TEMP\'.
swc_set_element lt_message_container 'DOCUMENTNAME' vbeln.
swc_set_element lt_message_container 'DOCUMENTTYPE' 'PDF'.
swc_set_element lt_message_container 'DOCUMENTSIZE' lv_doc_size.
swc_set_element lt_message_container 'FILEEXTENSION' 'pdf'.
swc_set_element lt_message_container 'LinkAttachement' lo_message.
swc_set_table lt_message_container 'DocumentContent' ls_job_info-otfdata[].

* Refresh to get the reference of create 'MESSAGE' object for attachment
swc_refresh_object lo_message.
swc_call_method lo_message 'CREATE' lt_message_container.

* Get Key of new object
swc_get_object_key lo_message lv_message_key.

* Now we have attachment as a business object instance. We can now
* attach it to our main business object instance.

* Create main BO object_a
DATA: lo_is_object_a TYPE borident.
lo_is_object_a-objkey = vbeln.
lo_is_object_a-objtype = 'VBRK'.

* Create attachment BO object_b
DATA: lo_is_object_b TYPE borident.
lo_is_object_b-objkey = lv_message_key.
lo_is_object_b-objtype = 'MESSAGE'.

DATA x_reltyp LIKE breltyp-reltype VALUE 'ATTA'.

CALL FUNCTION 'BINARY_RELATION_CREATE'
EXPORTING
obj_rolea = lo_is_object_a
obj_roleb = lo_is_object_b
relationtype = x_reltyp
EXCEPTIONS
OTHERS = 1.

ENDFORM. "crear_anexo
_______________________________________________________

He realizado numerosas pruebas modificando los valores de lt_message_container pero no he conseguido que el documento anexado sea el que he creado en el primer paso.

Evidentemente hay algo que no estoy haciendo bien pero no sé verlo. Por favor, alguien puede ofrecerme una pista.

Muchas gracias por anticipado

calanis
29/05/10, 01:04:36
Hola

Disculpa me es difícil identificar bien el error si no veo el contexto completo, pero intentaría lo siguiente:


Por lo que observo la tabla interna ls_job_info-otfdata[] te retorna los datos en OTF y se lo asignas en esta línea.
swc_set_table lt_message_container 'DocumentContent' ls_job_info-otfdata[].

Ahora, considero que esta otra tabla interna lines[] te retorna los datos ya en PDF, por lo que solo la reemplazaría por esta.
swc_set_table lt_message_container 'DocumentContent' lines[].


Saludos
Carlos Alanis

SAPLH
31/05/10, 09:53:11
Hola Carlos:

Añado el código que te falta, es el punto de la facturación donde se ejecuta el smartforms. Hasta ese punto todo es correcto, después lo convierto a PDF y también funciona bien y por último añado el link contra el GOS ... aparentemente casi funciona porque en la ventana "Lista de Objetos" del servicio de objetos veo el item con el documento, pero al hacer doble click no puedo abrirlo.

La posibilidad de cambiar lines[] por ls_job_info-otfdata[] la había probado con resultado negativo.

Intuyo que debe ser cualquier propiedad mal cargada o ausente, pero no doy con la solución.

En cualquier caso, muchas gracias por tu colaboración,
SAPLH


REPORT zrlb_invoice.

* declaration of data
INCLUDE zrlb_invoice_data_declare.
* definition of forms
INCLUDE zrlb_invoice_form01.
INCLUDE zrlb_print_forms.

*En el formulario se averigua en base al cliente si debe llevar marcas
*de ensobrado o no.
*Esta variable es para cuando se trata de una impresión de un
*grupo de facturas, ya q las debe introducir todas en el mismo sobre.
*A = Acumular (Sólo marcará las 2 líneas de acumular facturas)
*C = Cerrar (Cerrará el ensobrado con 4 líneas en función de las páginas
* q. tenga la factura, si tiene 3 pags cerrará en la última)
DATA: gv_modo_ensobrar(1) TYPE c.

* Estructuras adicionales para convetir a PDF ...

DATA: ls_print_data_to_read TYPE lbbil_print_data_to_read.
DATA: ls_bil_invoice TYPE lbbil_invoice.
DATA: lf_fm_name TYPE rs38l_fnam.
DATA: ls_control_param TYPE ssfctrlop.
DATA: ls_composer_param TYPE ssfcompop.
DATA: ls_recipient TYPE swotobjid.
DATA: ls_sender TYPE swotobjid.
DATA: lf_msgclass LIKE tnapr-kschl.
DATA: lf_formname TYPE tdsfname.
DATA: ls_addr_key LIKE addr_key.
DATA: ls_dlv-land LIKE vbrk-land1.
DATA: ls_job_info TYPE ssfcrescl.
DATA: ls_job_output_options TYPE ssfcresop.
DATA: lv_doc_content TYPE STANDARD TABLE OF soli-line WITH HEADER LINE.
DATA: lv_doc_size TYPE i.
DATA: etb_objcont TYPE soli_tab.
DATA: etb_objhead TYPE soli_tab.
DATA: file TYPE string.
DATA: vbeln LIKE vbrk-vbeln.
DATA: lines TYPE tsftext.
*DATA: lines LIKE tline OCCURS 100 WITH HEADER LINE.
*---------------------------------------------------------------------*
* FORM ENTRY
*---------------------------------------------------------------------*
FORM entry USING return_code us_screen.

DATA: lf_retcode TYPE sy-subrc.
CLEAR retcode.
xscreen = us_screen.
PERFORM processing USING us_screen
CHANGING lf_retcode.
IF lf_retcode NE 0.
return_code = 1.
ELSE.
return_code = 0.
ENDIF.

ENDFORM. "ENTRY
*---------------------------------------------------------------------*
* FORM PRINT_FACT_ZVF31
*---------------------------------------------------------------------*
FORM print_fact_zvf31 USING lp_modo_ensobrar
CHANGING lp_retcode.

CLEAR: gv_modo_ensobrar.

gv_modo_ensobrar = lp_modo_ensobrar.
PERFORM entry USING lp_retcode ' '.

ENDFORM. "ENTRY
*---------------------------------------------------------------------*
* FORM PROCESSING *
*---------------------------------------------------------------------*
FORM processing USING proc_screen
CHANGING cf_retcode.

DATA: l_langu_form LIKE ssfctrlop-langu,
l_kunnr LIKE vbpa-kunnr.

CLEAR: l_langu_form,
l_kunnr.

* MessageClass & SmartForm from customizing table TNAPR
lf_msgclass = tnapr-kschl.
lf_formname = tnapr-sform.

* determine print data
PERFORM set_print_data_to_read USING lf_formname
CHANGING ls_print_data_to_read
cf_retcode.

IF cf_retcode = 0.
* select print data
PERFORM get_data USING ls_print_data_to_read
CHANGING ls_addr_key
ls_dlv-land
ls_bil_invoice
cf_retcode.
ENDIF.

IF cf_retcode = 0.

PERFORM set_print_param USING ls_addr_key
ls_dlv-land
CHANGING ls_control_param
ls_composer_param
ls_recipient
ls_sender
cf_retcode.

* Destinatario de correspondencia
SELECT SINGLE kunnr FROM vbpa INTO l_kunnr
WHERE vbeln = ls_bil_invoice-hd_gen-bil_number
AND parvw = 'Z3'.
IF sy-subrc NE 0.

* Destinatario de factura
SELECT SINGLE kunnr FROM vbpa INTO l_kunnr
WHERE vbeln = ls_bil_invoice-hd_gen-bil_number
AND parvw = 'RE'.

ENDIF.

SELECT SINGLE spras FROM kna1 INTO l_langu_form
WHERE kunnr = l_kunnr.

ls_control_param-langu = l_langu_form.

*Si el modo de ensobrado no está relleno es que la impresión procede del
*estándar, con lo cual, cerraremos por factura NO por grupo de facturas
IF gv_modo_ensobrar IS INITIAL.
gv_modo_ensobrar = 'C'.
ENDIF.

ENDIF.

IF cf_retcode = 0.
* determine smartform function module for invoice
CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
EXPORTING formname = lf_formname
* variant = ' '
* direct_call = ' '
IMPORTING fm_name = lf_fm_name
EXCEPTIONS no_form = 1
no_function_module = 2
OTHERS = 3.
IF sy-subrc <> 0.
* error handling
cf_retcode = sy-subrc.
PERFORM protocol_update.
ENDIF.
ENDIF.

IF cf_retcode = 0.
PERFORM check_repeat.
IF ls_composer_param-tdcopies EQ 0.
nast_anzal = 1.
ELSE.
nast_anzal = ls_composer_param-tdcopies.
ENDIF.
ls_composer_param-tdcopies = 1.
DO nast_anzal TIMES.
* In case of repetition only one time archiving
IF sy-index > 1 AND nast-tdarmod = 3.
nast_tdarmod = nast-tdarmod.
nast-tdarmod = 1.
ls_composer_param-tdarmod = 1.
ENDIF.
IF sy-index NE 1 AND repeat IS INITIAL.
repeat = 'X'.
ENDIF.

IF lf_msgclass = 'ZRD3'.
ls_control_param-getotf = 'X'.
ls_control_param-no_dialog = 'X'.
ls_control_param-preview = 'X'.
ls_composer_param-tdarmod = '1'.
ls_composer_param-tdnoprev = 'X'.
ls_composer_param-tdtitle = sy-title.
ls_composer_param-tdnewid = 'X'.
ENDIF.

* call smartform invoice ...

CALL FUNCTION lf_fm_name
EXPORTING
archive_index = toa_dara
archive_parameters = arc_params
control_parameters = ls_control_param
* mail_appl_obj =
mail_recipient = ls_recipient
mail_sender = ls_sender
output_options = ls_composer_param
user_settings = space
is_bil_invoice = ls_bil_invoice
is_nast = nast
is_repeat = repeat
i_modo_ensobrar = gv_modo_ensobrar
IMPORTING job_output_info = ls_job_info
job_output_options = ls_job_output_options
* document_output_info =
EXCEPTIONS formatting_error = 1
internal_error = 2
send_error = 3
user_canceled = 4
OTHERS = 5.
IF sy-subrc <> 0.
* error handling
cf_retcode = sy-subrc.
PERFORM protocol_update.
* get SmartForm protocoll and store it in the NAST protocoll
PERFORM add_smfrm_prot.
ELSE.
IF lf_msgclass = 'ZRD3'.
vbeln = ls_bil_invoice-hd_gen-bil_number.
PERFORM convert_to_pdf.
PERFORM crear_anexo.
ENDIF.
ENDIF.
ENDDO.
* get SmartForm spoolid and store it in the NAST protocoll
DATA ls_spoolid LIKE LINE OF ls_job_info-spoolids.
LOOP AT ls_job_info-spoolids INTO ls_spoolid.
IF ls_spoolid NE space.
PERFORM protocol_update_spool USING '342' ls_spoolid
space space space.
ENDIF.
ENDLOOP.
ls_composer_param-tdcopies = nast_anzal.
IF NOT nast_tdarmod IS INITIAL.
nast-tdarmod = nast_tdarmod.
CLEAR nast_tdarmod.
ENDIF.

ENDIF.

* get SmartForm protocoll and store it in the NAST protocoll
* PERFORM ADD_SMFRM_PROT.

ENDFORM. "PROCESSING

calanis
31/05/10, 21:37:30
Hola

Lee esto que te puede ayudar, por que si algo esta faltando ahí :S creo que es la sentencia COMMIT, pero mejor chequea contra el Link y si tenes ganas este tambien.

Saludos.
Carlos Alanis