This Cross-Application Fiori APP allows to download any Output of Print forms in PDF format based on FDP (Form data provider interface). Just by choosing the application/document type (e.g. MM-Purchase Order, SD-Billing Document,..etc) and selecting the document criteria, it produces the list of documents with the downloadable PDF links.
Note- I am very grateful to the author(Prabhjot Bhatia ) of the blog ABAP Programming Model for SAP Fiori – 13 – How to Preview and Download PDF in Fiori Apps | , which provided me the tips on creating the downloadable PDF links.
Note- I have created 2 custom config tables to store some key name-value pairs(such as "sender country",..etc for Master and Content ADOBE Templates), which will be used in this APP. I must confess that this is a limitation in this APP development as the better approach is to derive these keys value dynamically.
You can create this APP in your environment with the following steps.
Step 1 - Create the following ABAP dictionary objects. Table 1 and 2 will be used as the configuration tables to retrieve key Name-Value pairs for Master and Content Adobe templates.
Table 1 - ZDCP_FP_IT_M_KEY
Table 2 - ZDCP_FP_PDF_FORM
Assign the Table 1 in the foreign key relationship to the field IV_OBJECT_TYPE in Table 1.
Maintenance view ZDCP_FP_FORMS_MV, which combines the Table 1 and 2.
Sample data for table 1 and 2
Note - By debugging CL_APOC_OR_H_UTILITY->_RENDER_DOCUMENT_MULTI in tcode mE22n, you can retrieve the standard name-value pairs such as RecieverpartnerNumber, sender countries,..etc. If you dig deeper, you could be able to retrieve these value dynamically based on document number(e.g. PO number) during runtime, instead of reading from configuration table.
Note- It is possible to add multiple ADOBE templates (both master and content) in the table ZDCP_FP_PDF_FORM. This allows to test multiple ADOBE layouts. In this sample data, Version 1 represent standard SAP ADOBE templates and Version 2 represent custom made templates.
Structure ZDCP_OBJECT_PDF_V2
Step 2 – Create the following FM ZGENERATE_PDF_XSTRING and the subroutine
FUNCTION ZGENERATE_PDF_XSTRING.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(IV_OBJECT_TYPE) TYPE STRING
*" REFERENCE(IV_OBJECT_NR) TYPE STRING
*" REFERENCE(IV_VERSION_NR) TYPE VERSNR_KK
*" REFERENCE(IV_FYEAR) TYPE /ACCGO/E_FISCAL_YEAR
*" REFERENCE(IV_CC) TYPE /ACCGO/E_COMPANYCODE_VH
*" EXPORTING
*" REFERENCE(EV_DOCUMENT_DATA) TYPE XSTRING
*" REFERENCE(EV_PAGES) TYPE FPPAGECOUNT
*" REFERENCE(EV_TRACE_STRING) TYPE STRING
*" REFERENCE(EV_STOP_PROCESSING) TYPE ABAP_BOOL
*" REFERENCE(EV_PDL_TYPE) TYPE APOC_PDL_TYPE
*" REFERENCE(ET_MESSAGE) TYPE CL_SOMU_FORM_SERVICES=>TY_GT_MESSAGE
*"----------------------------------------------------------------------
TYPES:
BEGIN OF ty_gs_fdp_key,
name TYPE string,
value TYPE string,
END OF ty_gs_fdp_key .
TYPES:
ty_gt_fdp_key TYPE STANDARD TABLE OF ty_gs_fdp_key WITH EMPTY KEY .
DATA wa_message TYPE LINE OF cl_somu_form_services=>ty_gt_message.
DATA: it_master_keys TYPE ty_gt_fdp_key .
DATA: ls_master_keys TYPE name2stringvalue_table, wa_ls_master_keys TYPE name2stringvalue.
*NAME2STRINGVALUE
DATA lv_pq_name TYPE pq_qname.
DATA lv_xml_in TYPE xstring.
DATA lv_stop TYPE boole_d.
DATA: it_key TYPE ty_gt_fdp_key, ls_appl_keys TYPE name2stringvalue_table, wa_ls_appl_keys TYPE ty_gs_fdp_key.
DATA lo_hlp TYPE REF TO if_apoc_or_h_factory_internal.
DATA lo_fp_srv TYPE REF TO if_apoc_somu_form_services.
DATA render_options TYPE cl_somu_form_services=>ty_gs_render_options.
DATA ls_merge_doc TYPE if_apoc_document_merge=>document_object.
DATA lt_msg TYPE cl_somu_form_services=>ty_gt_message.
DATA lt_msg_all TYPE cl_somu_form_services=>ty_gt_message.
DATA lv_xml_out TYPE xstring.
DATA lv_pdl_type TYPE apoc_pdl_type.
DATA: pdf_form TYPE fpwbformname VALUE 'ZZ1_DCP_MM_PUR_PURCHASE_ORDER', pdf_mfor TYPE apoc_form_master_template_id VALUE 'ZZ1_DCP_MM_PUR_ORDER_MASTER' .
DATA wa_zdcp_fp_forms_mv TYPE zdcp_fp_forms_mv.
PERFORM set_default_keys USING iv_object_type iv_object_nr iv_version_nr CHANGING ls_master_keys ls_appl_keys pdf_form pdf_mfor.
* Object Type specific
CASE iv_object_type.
WHEN 'PURCHASE_ORDER'.
wa_ls_appl_keys-name = 'PurchaseOrder'.
wa_ls_appl_keys-value = iv_object_nr.
APPEND wa_ls_appl_keys TO ls_appl_keys.
wa_ls_appl_keys-name = 'PurchaseOrderChangeFlag'.
wa_ls_appl_keys-value = ''.
WHEN 'BILLING_DOCUMENT'.
wa_ls_appl_keys-name = 'BillingDocument'.
wa_ls_appl_keys-value = iv_object_nr.
ENDCASE.
APPEND wa_ls_appl_keys TO ls_appl_keys.
*Validate the Document
CASE iv_object_type.
WHEN 'PURCHASE_ORDER'.
SELECT SINGLE ebeln FROM ekko INTO (lv_ebeln) WHERE ebeln = _object_nr.
IF sy-subrc NE 0.
wa_message-type = 'E'.
CONCATENATE 'PO ' iv_object_nr ' does not exist.' INTO wa_message-text.
APPEND wa_message TO et_message.
* MESSAGE i899(/cdbasis/msg) WITH 'PO ' iv_object_nr ' does not exist.'.
* LEAVE TO TRANSACTION 'Z_PO_ADOBE'.
ENDIF.
WHEN 'BILLING_DOCUMENT'.
SELECT SINGLE vbeln FROM vbrk INTO (lv_vbeln) WHERE vbeln = _object_nr.
IF sy-subrc NE 0.
wa_message-type = 'E'.
CONCATENATE 'Billing Document ' iv_object_nr ' does not exist.' INTO wa_message-text.
APPEND wa_message TO et_message.
* MESSAGE i899(/cdbasis/msg) WITH 'Billing Document ' iv_object_nr ' does not exist.'.
* LEAVE TO TRANSACTION 'Z_PO_ADOBE'.
ENDIF.
ENDCASE.
lo_hlp = cl_apoc_or_h_factory_internal=>get_helper_factory( ).
TRY.
" Get form provide services
lo_fp_srv = lo_hlp->get_somu_form_services( ).
TRY.
it_master_keys = ls_master_keys.
it_key = ls_appl_keys.
lo_fp_srv->get_document(
EXPORTING
* iv_master_form_name = 'ZZ1_DCP_MM_PUR_ORDER_MASTER'
iv_master_form_name = pdf_mfor
* iv_form_name = 'ZZ1_DCP_MM_PUR_PURCHASE_ORDER'
iv_form_name = pdf_form
it_key = it_key
* it_filter_select_option = ls_appl-filter_options
it_master_key = it_master_keys
iv_form_language = 'E'
iv_form_country = 'CA'
is_render_options = render_options
iv_print_queue_name = lv_pq_name
iv_xml = lv_xml_in
iv_disable_cache = 'X'
IMPORTING
ev_content = ev_document_data
ev_pages = ev_pages
ev_stop_processing = lv_stop
et_message = lt_msg
ev_xml = lv_xml_out
ev_pdl_type = lv_pdl_type ).
INSERT LINES OF lt_msg INTO TABLE lt_msg_all.
CATCH cx_somu_error INTO DATA(error_somu).
DATA(text_somu) = error_somu->get_text( ).
wa_message-type = 'E'.
wa_message-text = text_somu.
APPEND wa_message TO et_message.
* MESSAGE i899(/cdbasis/msg) WITH text_somu.
sy-subrc = 98.
ENDTRY.
CATCH cx_apoc_extern_services INTO DATA(error_apoc_services).
DATA(text_apoc) = error_apoc_services->get_text( ).
wa_message-type = 'E'.
wa_message-text = text_apoc.
APPEND wa_message TO et_message.
* MESSAGE i899(/cdbasis/msg) WITH text_apoc.
ENDTRY.
ENDFUNCTION.
FORM set_default_keys USING iv_object_type iv_object_nr iv_version_nr CHANGING ls_master_keys TYPE name2stringvalue_table ls_appl_keys TYPE name2stringvalue_table pdf_form pdf_mfor.
DATA: wa_ls_master_keys TYPE name2stringvalue, wa_ls_appl_keys TYPE name2stringvalue,
wa_zdcp_fp_forms_mv TYPE zdcp_fp_forms_mv.
SELECT SINGLE * FROM zdcp_fp_pdf_form INTO CORRESPONDING FIELDS OF wa_zdcp_fp_forms_mv
WHERE iv_object_type = iv_object_type
AND iv_version_nr = iv_version_nr.
SELECT SINGLE * FROM zdcp_fp_it_m_key INTO CORRESPONDING FIELDS OF wa_zdcp_fp_forms_mv
WHERE iv_object_type = iv_object_type.
wa_ls_master_keys-name = 'Recipient'.
wa_ls_master_keys-value = wa_zdcp_fp_forms_mv-name_par_04.
APPEND wa_ls_master_keys TO ls_master_keys.
wa_ls_master_keys-name = 'OutputRequestItem'.
wa_ls_master_keys-value = wa_zdcp_fp_forms_mv-name_par_05.
APPEND wa_ls_master_keys TO ls_master_keys.
wa_ls_master_keys-name = 'OutputControlApplicationObject'.
*wa_ls_master_keys-value = '4500000369'.
wa_ls_master_keys-value = iv_object_nr.
APPEND wa_ls_master_keys TO ls_master_keys.
wa_ls_master_keys-name = 'WatermarkText'.
wa_ls_master_keys-value = wa_zdcp_fp_forms_mv-name_par_07.
APPEND wa_ls_master_keys TO ls_master_keys.
wa_ls_master_keys-name = 'LocaleCountry'.
wa_ls_master_keys-value = wa_zdcp_fp_forms_mv-name_par_08.
APPEND wa_ls_master_keys TO ls_master_keys.
wa_ls_master_keys-name = 'LocaleLanguage'.
wa_ls_master_keys-value = wa_zdcp_fp_forms_mv-name_par_09.
APPEND wa_ls_master_keys TO ls_master_keys.
wa_ls_appl_keys-name = 'ReceiverPartnerNumber'.
wa_ls_appl_keys-value = wa_zdcp_fp_forms_mv-name_par_01.
APPEND wa_ls_appl_keys TO ls_appl_keys.
wa_ls_appl_keys-name = 'SenderCountry'.
wa_ls_appl_keys-value = wa_zdcp_fp_forms_mv-name_par_02.
APPEND wa_ls_appl_keys TO ls_appl_keys.
wa_ls_master_keys-name = 'SenderCountry'.
wa_ls_master_keys-value = wa_zdcp_fp_forms_mv-name_par_02.
APPEND wa_ls_master_keys TO ls_master_keys.
wa_ls_master_keys-name = 'RecipientRole'.
wa_ls_master_keys-value = wa_zdcp_fp_forms_mv-name_par_10.
APPEND wa_ls_master_keys TO ls_master_keys.
wa_ls_appl_keys-name = 'Language'.
wa_ls_appl_keys-value = wa_zdcp_fp_forms_mv-name_par_03.
APPEND wa_ls_appl_keys TO ls_appl_keys.
wa_ls_master_keys-name = 'PrintFormDerivationRule'.
wa_ls_master_keys-value = wa_zdcp_fp_forms_mv-name_par_11.
APPEND wa_ls_master_keys TO ls_master_keys.
wa_ls_master_keys-name = 'OutputControlApplicationObjectType'.
wa_ls_master_keys-value = wa_zdcp_fp_forms_mv-name_par_12.
APPEND wa_ls_master_keys TO ls_master_keys.
wa_ls_master_keys-name = 'OutputDocumentType'.
wa_ls_master_keys-value = wa_zdcp_fp_forms_mv-name_par_13.
APPEND wa_ls_master_keys TO ls_master_keys.
*Document specific
wa_ls_master_keys-name = 'OutputControlApplicationObject'.
wa_ls_master_keys-value = iv_object_nr.
APPEND wa_ls_master_keys TO ls_master_keys.
pdf_form = wa_zdcp_fp_forms_mv-content_form.
pdf_mfor = wa_zdcp_fp_forms_mv-master_form .
ENDFORM.
Note - In this FM, only the Application types PURCHASE_ORDER and BILLING_DOCUMENT are included. If you want to add additional Application types then add those type is the config tables 1 and 2 with appropriate values. Also add some additional code in the FM in the section "* Object Type specific".
Step 3 - Create a project in the tcode SEGW
Create the following entity get_pdf in this project using the structure ZDCP_OBJECT_PDF_V2.
Note- check on the field "Media author"
Generate the project and it will create the following classes.
Add the following code in the method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM
of the class ZCL_ZDCP_PDF_CROSS__01_DPC_EXT.
METHOD /iwbep/if_mgw_appl_srv_runtime~get_stream.
**TRY.
*CALL METHOD SUPER->/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM
** EXPORTING
** iv_entity_name =
** iv_entity_set_name =
** iv_source_name =
** it_key_tab =
** it_navigation_path =
** io_tech_request_context =
** IMPORTING
** er_stream =
** es_response_context =
* .
** CATCH /iwbep/cx_mgw_busi_exception.
** CATCH /iwbep/cx_mgw_tech_exception.
**ENDTRY.
DATA: ls_stream TYPE ty_s_media_resource, wa_zdcp_object_pdf TYPE zdcp_object_pdf_v2,
lw_key TYPE /iwbep/s_mgw_name_value_pair.
DATA ls_merge_doc TYPE if_apoc_document_merge=>document_object.
READ TABLE it_key_tab INTO lw_key INDEX 1.
wa_zdcp_object_pdf-iv_object_type = lw_key-value.
READ TABLE it_key_tab INTO lw_key INDEX 2.
wa_zdcp_object_pdf-iv_version_nr = lw_key-value.
READ TABLE it_key_tab INTO lw_key INDEX 3.
wa_zdcp_object_pdf-iv_object_nr = lw_key-value.
READ TABLE it_key_tab INTO lw_key INDEX 4.
wa_zdcp_object_pdf-iv_fyear = lw_key-value.
READ TABLE it_key_tab INTO lw_key INDEX 5.
wa_zdcp_object_pdf-iv_cc = lw_key-value.
CALL FUNCTION 'ZGENERATE_PDF_XSTRING'
EXPORTING
iv_object_type = wa_zdcp_object_pdf-iv_object_type
iv_object_nr = wa_zdcp_object_pdf-iv_object_nr
iv_version_nr = wa_zdcp_object_pdf-iv_version_nr
iv_fyear = wa_zdcp_object_pdf-iv_fyear
iv_cc = wa_zdcp_object_pdf-iv_cc
IMPORTING
ev_document_data = ls_merge_doc-document_data
* EV_PAGES =
* EV_TRACE_STRING =
* EV_STOP_PROCESSING =
* EV_PDL_TYPE =
* ET_MESSAGE =
.
ls_stream-value = ls_merge_doc-document_data.
ls_stream-mime_type = TEXT-001. "application/pdf"
copy_data_to_ref( EXPORTING is_data = ls_stream CHANGING cr_data = er_stream ).
ENDMETHOD.
Step 4 - Create the following CDS View entity ZCDS_OBJECT_PDF_V3
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Object information for ADOBE PDF'
@Metadata.ignorePropagatedAnnotations: true
@OData.publish: true
define view entity ZCDS_OBJECT_PDF_V3
with parameters
@Consumption.defaultValue : 'PURCHASE_ORDER'
@EndUserText.label: 'Appllication Type'
@Consumption.valueHelpDefinition: // Annotation to link parameter with CDS view which will help to generate Text
[ {
entity: { name: 'ZCDS_ZDCP_FP_PDF_FORM',
// entity: { name: 'I_OutputControlApplObjectType',
element: 'OutputControlApplObjectType'}
}]
p1_iv_object_type : apoc_appl_object_type,
@Consumption.defaultValue : '001'
@EndUserText.label: 'PDF Version(001(SAP),002(Custom)..etc'
p2_iv_version_nr : /accgo/e_ovd_version,
//@Environment.systemField: #SYSTEM_DATE
@Consumption.defaultValue : '2025'
@EndUserText.label: 'Fiscal year'
p3_iv_fyear : /accgo/e_fiscal_year,
@Consumption.defaultValue : '1730'
@EndUserText.label: 'Company Code'
p4_iv_cc : /accgo/e_companycode_vh
as select from I_OutputControlApplObjectType as objtype
//association [0..1] to I_OutputControlApplObjectType as _ObjType on $projection.iv_object_type = _ObjType.OutputControlApplObjectType
left outer join zdcp_fp_pdf_form as pdfform on objtype.OutputControlApplObjectType = pdfform.iv_object_type
// left outer join ZCDS_ZDCP_FP_PDF_FORM as pdfform on objtype.OutputControlApplObjectType = pdfform.iv_object_type
left outer join ekko as po on objtype.OutputControlApplObjectType = 'PURCHASE_ORDER'
left outer join vbrk as bill on objtype.OutputControlApplObjectType = 'BILLING_DOCUMENT'
// association [0..1] to I_OutputControlApplObjectType as _ObjType on $projection.iv_object_type = _ObjType.OutputControlApplObjectType
{
.lineItem: [ {
position: 10
} ]
// .selectionField: [{position: 10 }]
// @Consumption.filter.defaultValue: 'PURCHASE_ORDER'
@EndUserText.label: 'Appllication Type'
// @ObjectModel.foreignKey.association: '_ObjType'
key objtype.OutputControlApplObjectType as iv_object_type,
.lineItem: [ {
position: 20
} ]
.selectionField: [{position: 20 }]
@EndUserText.label: 'Document Number'
key
case
when objtype.OutputControlApplObjectType = 'PURCHASE_ORDER' then po.ebeln
when objtype.OutputControlApplObjectType = 'BILLING_DOCUMENT' then bill.vbeln
else 'Under Construction'
end as iv_object_nr,
.lineItem: [{ type: #WITH_URL , url: 'valueLink', position: 30}]
@EndUserText.label: 'PDF'
@ObjectModel.readOnly: true
'Download PDF->|' as showPdf,
case
when objtype.OutputControlApplObjectType = 'PURCHASE_ORDER' then
concat('/sap/opu/odata/sap/ZDCP_PDF_CROSS_APP2_SRV/get_pdfSet(',concat(concat('IvObjectType=''', objtype.OutputControlApplObjectType), concat(concat(''',IvVersionNr=''',pdfform.iv_version_nr),concat(concat(''',IvObjectNr=''',po.ebeln), concat(concat(''',IvFyear=''',$parameters.p3_iv_fyear),concat(concat(''',IvCc=''', po.bukrs),''')/$value'))))))
when objtype.OutputControlApplObjectType = 'BILLING_DOCUMENT' then
// concat('/sap/opu/odata/sap/ZDCP_PDF_CROSS_APP2_SRV/get_pdfSet(',concat(concat('IvObjectType=''', objtype.OutputControlApplObjectType), concat(concat('IvVersionNr=','000'),concat(concat('IvObjectNr=',bill.vbeln), concat(concat('IV_FYEAR=','0000'),concat('IV_CC=', bill.bukrs))))))
concat('/sap/opu/odata/sap/ZDCP_PDF_CROSS_APP2_SRV/get_pdfSet(',concat(concat('IvObjectType=''', objtype.OutputControlApplObjectType), concat(concat(''',IvVersionNr=''',pdfform.iv_version_nr),concat(concat(''',IvObjectNr=''',bill.vbeln), concat(concat(''',IvFyear=''',$parameters.p3_iv_fyear),concat(concat(''',IvCc=''', bill.bukrs),''')/$value'))))))
else ''
end as valueLink
//Associations
// _ObjType
}
where
objtype.OutputControlApplObjectType = $parameters.p1_iv_object_type
and pdfform.iv_version_nr = $parameters.p2_iv_version_nr
Step 5 - Create a Fiori APP based on the CDS View entity ZCDS_OBJECT_PDF_V3 by choosing the option "SAP Fiori generator" in the "New Project From Template"
Then Choose the following option
Then choose the appropriate system with the service ZCDS_OBJECT_PDF_V3_CDS, which was generated from the CDS View ZCDS_OBJECT_PDF_V3.
Then choose the following Main entity
Then enter the appropriate Project attributes
Clicking the FINISH button will create the FIORI Application, which you can test.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 13 | |
| 8 | |
| 7 | |
| 6 | |
| 6 | |
| 5 | |
| 5 | |
| 4 | |
| 4 | |
| 4 |