Custom Adobe Forms in SAP S/4 HANA Public Cloud using Developer Extensibility
Share

[[{“value”:”

Introduction

  • Custom Adobe forms can be created in SAP S/4 HANA Public Cloud using Developer Extensibility using Form Objects.
  • OData Service can be created to get Form details.

Process to Develop Custom Adobe Forms in SAP S4HANA Public Cloud using Developer Extensibility

Forms Objects

  • Creating Forms Objects in the Form editor allows for the generation of print and interactive forms using Adobe Document Services.
  • Forms Objects can be created in the Form editor.
  • Print and interactive forms can be generated using Adobe Document Services (ADS) by the Forms Object.
  • The main part of Forms Object is layout form design file (XDP format by Adobe).
  • Adobe LiveCycle Designer is required for the development of XDP layout file.

Creating Form Objects

  • A Form Object can be created in ABAP development tools for Eclipse (ADT) using the creation wizard

Print Forms

ADS Rendering in ABAP environment

  • In the ABAP environment with Adobe Document Services (ADS), rendering refers to the process of taking an Adobe XML Form (XFA) which is essentially a structured template containing layout, design, and data placeholders and producing a final output document.
  • The Adobe Document Services (ADS) can render Adobe XML Forms (XFA) to PDF documents and other print formats.
  • The application sends the data and the form template using a secure connection and the service returns the rendered document.
  • The rendered documents can be used by the applications for the screen output or for the output into the print queue.

Retrieve Stored Form Templates

Form templates designed with the Adobe LiveCycle Designer can be uploaded directly to the system using ABAP development tools for Eclipse.

The class CL_FP_FORM_READER enables the usage of uploaded form templates during runtime.

Initiate the Form Template Reader

Initiate the class by providing the name of the uploaded form template.

data(lo_reader) = cl_fp_form_reader=>create_form_reader( ‘MY_FORM_NAME’ ).

Read Layout Content to be Used by ADS Rendering Call

The layout can also be retrieved by the reader class.

The GET_LAYOUT method has the returning parameter RV_LAYOUT, it returns XML as XSTRING

RAP Data Services for Print Forms

  • The XML data for print form rendering can be obtained from the RAP Business Services.
  • The data model can be defined just as well as the RAP Service Definition.
  • The CL_FP_FDP_SERVICES class provides the ABAP API to receive the data in xml format for the use in print forms.
  • XML Schema Definition (XSD) used for the design of print forms in the Adobe LiveCycle Designer.

Initiate Business Data Reader

To supply the rendering operation with business data, a reuse service can be applied.

Service definition needs to be created previously.

The service definition doesn’t need a binding for RAP Data Services for print forms.

Initiate the reuse utility by specifying the service definition.

DATA(lo_fdp_api) = cl_fp_fdp_services=>get_instance( ‘FP_FDP_SERVICE_EX1’ ).

Specify the key parameters.

This is required to read the data for a specific item.

The reuse utility offers the functionality to retrieve all key fields for the service definition.

DATA(lt_keys) = lo_fdp_api->get_keys( ).

Once the array with key values has been retrieved, the keys that fit are assigned to the document to be output.

lt_keys[ name = ‘UUID’ ]-value = ‘4500000001’.

Retrieve XML Data from Service Definition

The READ_TO_XML_V2 method retrieves the data structure of the service definition for a specific item.

It has the Importing parameters IT_SELECT – Key parameters, IV_LANGUAGE (Optional).

It has the returning parameter RV_XML – Resulting XML as XSTRING.

TRY.
DATA(lv_data) = lo_fdp_api->read_to_xml_v2( lt_keys ).
CATCH cx_fp_fdp_error INTO DATA(lo_exception).
ENDTRY.

Retrieve XML Schema Definition from Service Definition

The GET_XSD_V2 method retrieves the XML Schema Definition (XSD) for the service definition.

It has the returning parameter RV_XML, it returns XSD as XSTRING.

TRY.
DATA(lv_xml) = lo_fdp_api->get_xsd_v2( ).
CATCH cx_fp_fdp_error INTO DATA(lo_exception).
ENDTRY

Runtime API for ADS Rendering Calls

The CL_FP_ADS_UTIL class provides the ABAP Runtime API for Adobe Document Services (ADS) rendering calls.

It contains the public method RENDER_PDF to be used for the Rendering PDF.

The PDF rendering process on ADS creates the PDF file to be printed (or print output format) using both formats

The XDP form template file is a description of the form layout design in Adobe XFA format.

The supported data binding type is an XML data schema.

The data XML file contains the data that corresponds to the used data schema in the XDP form template.

Rendering PDF

The RENDER_PDF method calls the ADS to render print PDF using the XDP form file and the XML data file. 

TRY.

*Render PDF
cl_fp_ads_util=>render_pdf(
EXPORTING
iv_xml_data = lv_xml_data
iv_xdp_layout = lv_xdp
iv_locale = ‘de_DE’
is_options = ls_options
IMPORTING
ev_pdf = ev_pdf
ev_pages = ev_pages
ev_trace_string = ev_trace_string ).
CATCH cx_fp_ads_util INTO lx_fp_ads_util.
ENDTRY.

Importing Parameters

IV_XML_DATA – XML data

IV_XDP_LAYOUT – Adobe XDP form template

IV_LOCALE – Locale for rendering the language language_COUNTRY, (en_US)

IS_OPTIONS – PDF rendering parameters (optional)

Exporting Parameters

EV_PDF – PDF rendering result

EV_PAGES – Pages

EV_TRACE_STRING – Trace string

Creating Data Provider

Create Data Model

Create a data model, add the annotation to the CDS View to act a data provider for FORM Object.

      @ObjectModel.supportedCapabilities: [ #OUTPUT_FORM_DATA_PROVIDER ]

            supportedCapabilities defines which features or capabilities are supported by the CDS view or entity.

           #OUTPUT_FORM_DATA_PROVIDER is a specific capability flag that indicates the CDS entity can act as a data provider for output forms.

CDS View – ZI_FORM_PO_HD

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Form PO’
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.supportedCapabilities: [ #OUTPUT_FORM_DATA_PROVIDER ]
define root view entity ZI_FORM_PO_HD
as select from ZI_PO_HD_DT
{
key PoNum,
Supplier,
PurOrg,
CompCod,
PurGrp,
CrDt,
_its
}

Data Source CDS View – ZI_PO_HD_DT

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘PO Header’
@Metadata.ignorePropagatedAnnotations: true
define root view entity ZI_PO_HD_DT
as select from ztb_po_hdr
association [0..*] to ZI_PO_ITS as _its on $projection.PoNum = _its.PoNum
{
key po_num as PoNum,
supplier as Supplier,
pur_org as PurOrg,
comp_cod as CompCod,
pur_grp as PurGrp,
cr_dt as CrDt,
_its
}

Custom Table

@EndUserText.label : ‘PO Header’
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #ALLOWED
define table ztb_po_hdr {

key client : abap.clnt not null;
key po_num : abap.char(10) not null;
supplier : abap.char(10);
pur_org : abap.char(5);
comp_cod : abap.char(5);
pur_grp : abap.char(5);
cr_dt : abap.dats;

}

Create Service Definition

For a service definition, a leading entity can be defined using annotation

       @ObjectModel.leadingEntity.name: ”

  Add the CDS View as a leading entity.

@EndUserText.label: ‘Service Definition of PO Form’
@ObjectModel.leadingEntity.name: ‘ZI_FORM_PO_HD’
define service ZSR_FORM_PO_HD {
expose ZI_FORM_PO_HD;
}

Service Definition ZSR_FORM_PO_HD is a Data provider for Form Object.

Service Binding

The service definition doesn’t need a binding for RAP Data Services for print forms.

YogiPavan_4-1772951096266.png

Creating Form Object

Create a Form Object with creation wizard from the main menu, toolbar, Project Explorer, or using a shortcut.

YogiPavan_5-1772951096268.png

Enter the name and description of a form.

YogiPavan_6-1772951096269.png

Select Next, assign a transport request, and select finish.

A new form is created and opened in the Form Editor.

YogiPavan_7-1772951096273.png

A Data Provider now needs to be specified, which is defined in the system as a service containing the business data for this form.

In the General Information section, define the properties of the form

  • In the Data provider field, specify the service definition that should be used for fetching the business data for a form.
  • The Embed Font field should be enabled if the fonts are to be embedded into the generated PDF.
  • The Reduce Data Volume field should be enabled if the generated business data is to be filtered to only contain fields bound by fields in the form layout.

Choose Browse option to view the list of Data Providers.

YogiPavan_8-1772951096276.png

Added the Data Provider ZSR_FORM_PO_HD to the Form

YogiPavan_9-1772951096280.png

In the action menu, three options

  • Download Schema: Download the schema of the linked Data provider as an xsd file which can be imported into Adobe LiveCycle Designer for SAP solutions.
  • Upload Layout: Upload a layout file (*.xdp) created by Adobe LiveCycle Designer for SAP solutions (make sure the form should save before uploading a layout file).
  • Download Layout: Download the current layout uploaded to the form.

YogiPavan_10-1772951096287.png

Choose Download Schema to create a new layout for the form.

YogiPavan_11-1772951096291.png

Export and save schema to local files.

YogiPavan_12-1772951096312.png

YogiPavan_13-1772951096315.png

Open the Adobe Life Cycle Designer

YogiPavan_14-1772951096319.png

Create a new blank form

YogiPavan_15-1772951096321.png

YogiPavan_16-1772951096329.png

YogiPavan_17-1772951096335.png

Blank Form is created

YogiPavan_18-1772951096343.png

Choose File -> New Data Connection

YogiPavan_19-1772951096346.png

Choose XML Schema

YogiPavan_20-1772951096354.png

YogiPavan_21-1772951096362.png

Import the XML Schema File

YogiPavan_22-1772951096369.png

YogiPavan_23-1772951096376.png

YogiPavan_24-1772951096383.png

Data Connection is added.

YogiPavan_25-1772951096389.png

Design the layout

YogiPavan_26-1772951096394.png

Save the layout file (XDP file) to local files.

YogiPavan_27-1772951096404.png

Upload the Layout to the Form Object

YogiPavan_28-1772951096405.png

YogiPavan_29-1772951096409.png

YogiPavan_30-1772951096415.png

YogiPavan_31-1772951096418.png

Layout is uploaded, save the form object

YogiPavan_32-1772951096420.png

Activate the Form Object

YogiPavan_33-1772951096422.png

Layout can be downloaded with Download Layout option

YogiPavan_34-1772951096423.png

YogiPavan_35-1772951096428.png

Consuming the Form using Custom Entity

Custom Entity

Create a custom entity, add the form related fields and add the annotation to make its content as attachment.

@Semantics.largeObject:{ mimeType: ‘MimyType’, fileName: ‘FileName’,
contentDispositionPreference: #ATTACHMENT }

Add the ABAP Class to implement the form access.

@EndUserText.label: ‘PO Form’
@Metadata.allowExtensions: true
@ObjectModel.query.implementedBy: ‘ABAP:ZCL_FORM_PO’
define custom entity ZI_FORM_PO

{
key PO : ebeln;
@Semantics.largeObject:{ mimeType: ‘MimyType’, fileName: ‘FileName’, contentDispositionPreference: #ATTACHMENT }
Form : abap.rawstring( 0 );
FileName : abap.char( 30 );
MimyType : abap.char( 50 );
}

Class- ZCL_FORM_PO

CLASS zcl_form_po DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.

PUBLIC SECTION.
INTERFACES if_rap_query_provider.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS

CLASS zcl_form_po IMPLEMENTATION.

METHOD if_rep_query_provider~select

DATA: 1s_form TYPE zi_form_po,
it_form TYPE TABLE OF zi_form_po.

TRY.

DATA(it_filter_conds) = io_request->get_filter()->get_as_ranges().
LOOP AT it_filter_conds INTO DATA(1s_filter_conds).
IF ls_filter_conds-name EQ ‘PO’.
READ TABLE ls_filter_conds-range INTO DATA(ls_rng) INDEX 1.
IF sy-subrc EQ 0.
DATA(lv_po) = ls_rng-low.
ENDIF.
ENDIF
CLEAR: ls_rng.
ENDLOOP.

DATA(lv_paging) = io_request->get_paging( )->get_offset( ).
DATA(lv_filters) = io_request->get_filter( )->get_as_sql_string( ).

CATCH cx_rap_query_filter_no_range INTO DATA(cx_mg).

IF 1v_po 15 INITIAL.
lv_po = ‘4500000001’.
ENDIF.

TRY.
“Initiate the Fore Template Reader
DATA(lo_reader) = cl_fp_form_reader->create_form_reader( iv_formname = ‘ZFORM_PO’ ).
“Read Layout Content to be Used by ADS Rendering Call
DATA(lv_layout) = lo_reader-get_layout().
CATCH cx_fp_form_reader INTO DATA(ls_cx_fp_form_reader).
ENDTRY.

TRY.
“Get instance of Form
DATA(lo_fdp_api) = cl_fdp_services->get instance(
iv service definition = ‘ZSR_FORM_PO_HD’
” iv root node =
iv_max_depth = 1 ).

“Retrieve x Data from Service Definition
DATA(ls_keys) = lo_fdp_api->get_keys( ).
it_keys[ name = ‘PONUM’ ]->value = lv_po.

DATA(lv_data) = lo_fdp_api->read_to_xml_v2(
it select = it_keys
“it_select_add =
“iv_language = SY-LANGU
).

“Retrive XML Schema Definition from Definition
DATA(lv_xml) = lo_fdp_api->get_xsd_v2( ).

CATCH cx_fp_fdp_error INTO DATA(lo_exception).
ENDTRY.

TRY.
“Rendering PDF
cl_fp_ads_util=>render_pdf(
EXPORTING
iv_xml_data = lv_data
iv_xdp_layout = lv_layout
iv_locale = ‘en_US’
” i_options =
IMPORTING
ev_pdf = DATA(ev_pdf)
ev_pages =
ev_trace_string =
).

CATCH cx_fp_ads_util INTO DATA(lo_fp_ads_util).

ENDTRY.

ls_form-po = lv_po.
ls_form-filename = ‘Form_PO.pdf’.
ls_form-mimytype = ‘application/pdf’.
ls_form-form = ev_pdf.
APPEND ls_form TO it_form.

io_response->set_data( it_form ).
io_response->set_total_number_of_records( lines( it_form ) ).

ENDMETHOD.
ENDCLASS.

Service Definition

Create a Service Definition, expose the entity.

YogiPavan_40-1772951133796.png

@EndUserText.label: ‘FORM_PO’
define service ZSD_FORM_PO {
expose ZI_FORM_PO;
}

Service Binding – Web API

Create a Service Binding with type OData V4 – Web API

YogiPavan_41-1772951133801.png

Click on Service URL to access it.

Service URL

YogiPavan_42-1772951133803.png

Access form details

YogiPavan_43-1772951133807.png

Download Form with URL

Download the Form with accessing the service URL by passing document number.

/sap/opu/odata4/sap/zsrb_form_po/srvd_a2x/sap/zsd_form_po/0001/ZI_FORM_PO(‘4500000001’)/Form

YogiPavan_44-1772951133808.png

Form is downloaded

YogiPavan_45-1772951133811.png

Service Binding – UI

Create a Service Binding with type OData V4 – UI

YogiPavan_46-1772951133816.png

Download Form with UI

Choose Preview in service binding to view UI

YogiPavan_47-1772951133819.png

Click on Form to download the Form

YogiPavan_48-1772951133821.png

Form is downloaded

YogiPavan_49-1772951133824.png

Debugging the Form Logic

Toggle Breakpoint is set

YogiPavan_50-1772951133828.png

Click on Form to trigger the breakpoint.

YogiPavan_51-1772951133830.png

Debugger got triggered.

YogiPavan_52-1772951133840.png

Variables with values

YogiPavan_53-1772951133845.png

Using CDS Views

CDS View

Create a CDS View with field having URL of Form

YogiPavan_54-1772951133858.png

@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘PO Header’
@Metadata.ignorePropagatedAnnotations: true
@Metadata.allowExtensions: true
define root view entity ZI_PO_HD
as select from ztb_po_hdr

association [0..*] to ZI_PO_ITS as _its on $projection.PoNum = _its.PoNum
{
key po_num as PoNum,
supplier as Supplier,
pur_org as PurOrg,
comp_cod as CompCod,
pur_grp as PurGrp,
cr_dt as CrDt,

// cast( ‘PO Form.pdf’ as abap.char( 20 )) as FileName,
//
// cast( ‘application/pdf’ as abap.char( 30 )) as MimeType,

concat( ‘/sap/opu/odata4/sap/zsb_form_po/srvd_a2x/sap/zsd_form_po/0001/ZI_FORM_PO(”’, concat( po_num, ”’)/Form’ )) as FormURL,

‘Print PDF’ as Form,

_its

}

Metadata Extension

Create metadata extension, add the fields with annotations and add the parameter type with #WITH_URL value, also url with value contains url field name

@Metadata.layer: #CORE
annotate entity ZI_PO_HD with
{
@UI.lineItem: [{ position: 10, label: ‘PO’ )]
@UI.identification: [{ position: 10, label: ‘PO’ }]
PoNum;

@UI.lineItem: [{ position: 40, label: ‘Form URL’, type: WITH URL, url:’FormURL’ }}
@UI.identification: [{ position: 40, label: ‘Form URL’, type: WITH URL, url: ‘FormURL’ }]
FormURL;

@UI.lineItem: [{position: 30,type: WITH URL, url: ‘FormURL’ }]
@UI.identification: [{ position: 30, type: #WITH URL, url: ‘FormURL’ }]
Form;
}

Service Definition

Create a Service Definition, expose the entity.

@EndUserText.label: ‘PO Hdr’
define service ZSR_POHDR_PR {
expose ZI_PO_HD;
}

Service Binding – UI

Create a Service Binding with type OData V4 – UI

YogiPavan_57-1772951133868.png

Download Form with UI

Choose Preview in service binding to view UI

YogiPavan_58-1772951133871.png

Click on Print PDF to download the Form

YogiPavan_59-1772951133874.png

Form is downloaded

YogiPavan_60-1772951133876.png

Click on Form URL to download the Form

YogiPavan_61-1772951133878.png

Form is downloaded

YogiPavan_62-1772951133880.png

References

Conclusion

Steps included to develop Custom Adobe Form in SAP S/4 HANA Public Cloud using Developer Extensibility

  • Creating Data Provider
  • Creating Form Objects
  • Consume the Form using Custom Entity

 

 

“}]] 

  Read More Technology Blog Posts by Members articles 

#abap

By ali