0% found this document useful (0 votes)
82 views

SAP_Adobe_form_using_ABAP_RESTful_Application_Programming_1739642330

The document outlines the steps to create a RAP application with an Adobe form for sales orders, including the development of a class for form content output in Base64 format. It details the creation of view entities, service definitions, and ODATA services, along with integration methods for displaying PDF documents in a Fiori application. Additionally, it provides code snippets for implementing the functionality and testing the application to ensure the PDF preview feature works correctly.

Uploaded by

V Chilukuri
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
82 views

SAP_Adobe_form_using_ABAP_RESTful_Application_Programming_1739642330

The document outlines the steps to create a RAP application with an Adobe form for sales orders, including the development of a class for form content output in Base64 format. It details the creation of view entities, service definitions, and ODATA services, along with integration methods for displaying PDF documents in a Fiori application. Additionally, it provides code snippets for implementing the functionality and testing the application to ensure the PDF preview feature works correctly.

Uploaded by

V Chilukuri
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

Steps to be followed.

1.Develop an Adobe form and common method to give the form content output as Base64
In this example I am using XML Based form interface but it is possible to use the ABAP
Dictionary based interface as well.
Form Name: ZZ1_SALE_ORDER

Here I am creating a new class and build the driver Method to call the form using and return
back the output form content
2.Now Let us build a RAP Application using Web UI -> Since we do not have Create, update and
other functionalities, I am not creating behavior definitions.

Create a new base View entity: ZI_RAP_SALE_ORD


@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Interface View for Sales Order'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define root view entity ZI_RAP_SALE_ORD
as select from I_SalesDocumentBasic
{
key SalesDocument,
SDDocumentCategory,
SalesDocumentType,
CreatedByUser,
CreationDate
}

Create a Consumption View for the Above View Entity: ZC_RAP_SALE_ORD


@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Consumption View for Sales Order'
@Metadata.allowExtensions: true
define root view entity ZC_RAP_SALE_ORD
provider contract transactional_query
as projection on ZI_RAP_SALE_ORD
{
key SalesDocument,
SDDocumentCategory,
SalesDocumentType,
CreatedByUser,
CreationDate
}

Create a Metadata Extension file for the Consumption view: ZMDE_RAP_SALE_ORD


We can also directly give annotations in consumption view itself, but as best practice I am
creating a new file to have these Annotation properties.
@Metadata.layer: #CORE
@Search.searchable: true
@UI.headerInfo:{
typeName: 'Sales Order',
typeNamePlural: 'Sale Orders',
title:{ type:#STANDARD,
label:'Document' ,
value:'SalesDocument'}

}
annotate view ZC_RAP_SALE_ORD with
{
@UI:{ lineItem: [{ position : 10}] }
@Search:{ defaultSearchElement: true,
fuzzinessThreshold: 0.7 }
SalesDocument;

@UI:{ lineItem: [{ position : 20}],


selectionField: [{ position : 20 }] }
@Search:{ defaultSearchElement: true,
fuzzinessThreshold: 0.7 }
SDDocumentCategory;

@UI:{ lineItem: [{ position : 30}] }


@Search:{ defaultSearchElement: true,
fuzzinessThreshold: 0.7 }
SalesDocumentType;

@UI:{ lineItem: [{ position : 40}],


selectionField: [{ position : 40 }] }
CreatedByUser;

@UI:{ lineItem: [{ position : 50}],


selectionField: [{ position : 50 }] }
CreationDate;

Create a new service definition for the Consumption View: ZSDEF_ZC_RAP_SALE_ORD


@EndUserText.label: 'Service Definition for Sale Order'
define service ZSDEF_ZC_RAP_SALE_ORD {
expose ZC_RAP_SALE_ORD;
}
Create a new Service Bindings for the Service Definition: ZBIND_ZC_RAP_SALE_ORD of
binding type ODATA V2 - UI and publish it. We can get the Metadata using Service URL

Create a new Fiori Application in Business Application Studio, Open BTP in Trail account and
make sure your system is configured in Destinations

3.Create a new Fiori Application using the template and use our above ODATA V2-UI service in
BAS
Once the Project is created and all the dependencies is installed. You can preview the application
by right click project1 and choose preview application -> start Fiori-run

Now our RAP Application is ready and separate form driver program is also ready. Let us
see on how to integrate it. This Integration can be Done by the following two ways
➔ Using SEGW ODATA -> GET_STREAM
➔ Using Custom View Entity that is implemented by ABAP class using Object model query
4.Create a New SEGW ODATA Project and Implement GET Stream method That consumes the
common driver program and send back the content

Entity properties

GET Stream Code:


""->Read Document ID from input
DATA(lv_doc) = VALUE numc10( IT_KEY_TAB[ name = 'docId' ]-value OPTIONAL ).

""->Call Form Driver Program to get the Form Content


DATA(lv_form_content) = new ZCL_SALE_ORDER_PDF( )->GET_SALE_ORDER_FORM(
im_so_order_no = conv #( lv_doc ) ).
""->Build Document Name and Set it in Header
set_header( is_header = VALUE #( name = 'Content-Disposition'
value = |inline; filename={ lv_doc };| ) ).
copy_data_to_ref( exporting
is_data = VALUE /IWFND/IF_MGW_CORE_RUNTIME=>TY_S_MEDIA_RESOURCE(
mime_type = 'application/pdf'
value = lv_form_content )
changing
cr_data = er_stream ).

Testing the SEGW ODATA Service


Add the Following line in the Interface View:ZI_RAP_SALE_ORD
We are adding two fields
ShowPDF -> Has the text Preview(SEGW) in the table
LinkToPDF -> Get Stream Link to be used to navigate as link to open PDF File
Lines:
'Preview(SEGW)' as ShowPDF,
concat('/sap/opu/odata/sap/ZODATA_TRAIN_SRV/SaleOrderDocumentSet(''',
concat(SalesDocument, ''')/$value')) as LinkToPDF

Add the Following highlighted Line in the Consumption view ZC_RAP_SALE_ORD to expose
the fields

Add the Following Lines in the Metadata extension file to establish the link to:
@UI:{
lineItem: [{ position : 60, label : 'PDF'}, { type : #WITH_URL, url:'LinkToPDF' }]
}
ShowPDF;
Testing the RAP Application- Now we can see the New Field as clickable link
On clicking the Link, the SEGW Service is called and PDF is shown

5.Using Custom View Entity that is implemented by ABAP class using Object model query
Create a new Custom View Entity: ZI_SALE_ORDER_PDF
@EndUserText.label: 'Sale Order PDF'
@ObjectModel.query.implementedBy: 'ABAP:ZCL_SALE_ORDER_PDF'
define custom entity ZI_SALE_ORDER_PDF
with parameters
p_so_document_id : vbeln
{
key so_doc_pdf : abap.string(0);
}

Create a new Class : ZCL_SALE_ORDER_PDF and use interface


IF_RAP_QUERY_PROVIDER and redefine the Select method
class ZCL_SALE_ORDER_PDF definition
public
final
create public .

public section.

interfaces IF_RAP_QUERY_PROVIDER .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS .

CLASS ZCL_SALE_ORDER_PDF IMPLEMENTATION.


METHOD if_rap_query_provider~select.
""->Internal Table Declaration
DATA : lt_pdf TYPE TABLE OF zi_sale_order_pdf.
""->Object Declaration
DATA : lo_somu_form_services TYPE REF TO cl_somu_form_services.

DATA : lv_form_out TYPE string.

TRY.
IF io_request->is_data_requested( ).
DATA(lv_offset) = io_request->get_paging( )->get_offset( ).
DATA(lv_page_size) = io_request->get_paging( )->get_page_size( ).
DATA(lv_max_rows) = COND #( WHEN lv_page_size = if_rap_query_paging=>page_size_unlimited
THEN 0 ELSE lv_page_size ) .

DATA(lt_params) = io_request->get_parameters( ).
""->Take the Input Parameter Name from Custom Entity which is using this ABAP Class
DATA(lv_so_doc_id) = VALUE numc10(
lt_params[ parameter_name = 'P_SO_DOCUMENT_ID' ]-value OPTIONAL ).
""->Call the PDF Content Common Driver Method
data(lv_so_form) = get_sale_order_form( im_so_order_no = conv #( lv_so_doc_id ) ).
IF lv_so_form IS NOT INITIAL.
""->Convert Xstring to Base64
CALL FUNCTION 'SCMS_BASE64_ENCODE_STR'
EXPORTING
input = lv_so_form
IMPORTING
output = lv_form_out.
ENDIF.
lt_pdf = VALUE #( ( so_doc_pdf = lv_form_out ) ).
io_response->set_total_number_of_records( 1 ).
io_response->set_data( lt_pdf ).
ENDIF.
CATCH cx_rap_query_provider.
ENDTRY.
ENDMETHOD.
ENDCLASS .

Create a new Service Definition for the Custom Entity: ZSDEF_SALE_ORD_PDF


@EndUserText.label: 'Service Definition for Sale Order PDF'
define service ZSDEF_SALE_ORD_PDF {
expose ZI_SALE_ORDER_PDF;
}
Create a new Service binding for the Custom Entity of type ODATA V2 Web API and publish it
Test the Service Definition using Service URL:

Since we get the Data in Base64 format we need to create a extension in the UI application.
Right Click the project and open guided Development
Choose the “1. Add Custom Action to page Using Extensions”, then give the Function Name and
click on create. This will add a new Controller file in the project

Now Choose the “2. Update the manifest”, then give the Entity Set as the root entity set, Action
Id, Row selection and Button text. Then click insert snippet
Extensions will be added by guided development in manifest file

Need to add the following lines in the Manifest.json file


->In the dataSources property:
->In the models property:
We can write out custom code in the added Controller file to open PDF Preview
To get the PDF data from RAP ODATA Web API

ListReportExt.controller.js
sap.ui.define([
"sap/m/MessageToast",
"sap/m/PDFViewer"

], function (MessageToast,PDFViewer) {
'use strict';
return {
getPdffromOdata: function () {
var oModel = this.getView().getModel("oPdfModel");
var oGrid =
this.getView().byId("project4::sap.suite.ui.generic.template.ListReport.view.ListReport::ZC_RAP_SALE_ORD--
responsiveTable");
// get Sales Order from selected index
var saleDocument = oGrid.getSelectedItem().getBindingContext().getObject().SalesDocument;
return new Promise((resolve, reject) => {
// Perform Read operation and document number as parameter to URL
oModel.read("/ZI_SALE_ORDER_PDF(p_so_document_id='" + saleDocument + "')/Set",
{
success: function (oData, Response) {
resolve(oData);
},
error: function (oError) {
reject(oError);
}
});
})
},
onShowSaleOrderPdf: async function (oEvent) {
var opdfViewer = new PDFViewer();
this.getView().addDependent(opdfViewer);
var oBusyDialog = new sap.m.BusyDialog({
title: 'Generating Form...'
});
oBusyDialog.open();
// Get the PDF data
var vPDF = await this.getPdffromOdata();
let base64EncodedPDF = vPDF.results[0].so_doc_pdf;
let decodedPdfContent = atob(base64EncodedPDF);
let byteArray = new Uint8Array(decodedPdfContent.length);
for (var i = 0; i < decodedPdfContent.length; i++) {
byteArray[i] = decodedPdfContent.charCodeAt(i);
}
var blob = new Blob([byteArray.buffer], {
type: 'application/pdf'
});
var pdfurl = URL.createObjectURL(blob);
jQuery.sap.addUrlWhitelist("blob"); // register blob url as whitelist
opdfViewer.setSource(pdfurl);
opdfViewer.setVisible(true);
opdfViewer.setTitle("Billing Document ");
opdfViewer.open();
oBusyDialog.close();
}
};
});

Now test the Application: Print Preview Button is added

You can select any Sale order to enable the Print Preview button and click it to open the PDF file

You might also like