Skip to Content
Technical Articles
Author's profile photo Abir Cherif

Create Adobe form with fragments as a copy of the standard.

Introduction

The Adobe form with fragments are part of the New Output Management for S/4 HANA Systems. In this blog post, I will explain, step by step, how to create a copy of this standard form with Fragments. Next, I will briefly compare the use of this form against the “standalone form” by giving advantages of its use.

Prerequisite

You must have Adobe live Cycle Designer installed on your PC.

What is the utility of services in the forms with fragments?

The ODATA service is a data provider. It gets data from the backend it generates an XML file.

What is the use of callback class?

It is responsible for calling the ODATA service to get the data, in XML format. This data will be used  in the call to the form interface to print it.

 

Comparison between the process of calling an Adobe Form with context (the standalone form) and Adobe form with fragments.

 

For the Adobe forms with context, the operation is simple. To print the form, we retrieve the data in a program and using this data, we call the function module of the form to print it.

But, for the Adobe form with fragments, in a callback class, we call an ODATA service to get the XML file that will be sent to the form to print it using the concept of binding available at Adobe layer (the XDP file of the form).

1

What is the advantage of adobe forms with fragments?

  • Reuse of the ODATA service: the ODATA service created in this form is a shared and reusable resource (whether in other forms or other programs). Whereas, the other types of forms are completely isolated and autonomous.
  • Speed and ease of development and maintenance: It is faster and easier to use ODATA services or methods, than to copy or recreate the contents of a new one.
  • Reusability of fragments: this type of form is based on fragments (.XDP file). These files can be reusable in several forms as indicated in this blog post.

 

Step by step to create an adobe form with fragment in copy of the standard form.

In this scenario, we will take the purchase order as an example.

Copy the standard form and OData :

  1. Create a ZSF_MM_PURCHASE_ORDER form as a copy of the standard (interface + form) MM_PUR_PURCHASE_ORDER via the SFP transaction.

2

 

The standard form uses the FDP_EF_PURCHASE_ORDER_SRV service as data provider.

In order to add our own fields to the service, we need to create a custom service.

3

 

     2. Create an empty project “ZFDP_PURCHASE_ORDER_AB” using the transaction SEGW.

4

    3. Use a data model by reference to create the entities types.

 

5

 

In this custom service, the reference is the standard service “FDP_EF_PURCHASE_ORDER_SRV”.

6

 

Select All the entity in the popup to get all the entity in the standard service imported to the custom service.

7

 

Save the service in the transport order.

8

 

4. Generate the OData service.

9

 

Copy the “Technical service name”, in our example it is “ZFDP_PURCHASE_ORDER_AB_SRV”. We will use it when adding it to the services catalog.

 

The service is generated successfully.

10

 

5. Enable the service Z in /IWFND/MAINT_SERVICE (service catalog).

 

Click the Add Service button.

11

 

Enter the service name “ZFDP_ PURCHASE_ORDER_AB_SRV” copied in “step4” and the system alias “LOCAL” and Click in “get services” button.

12

 

By clicking on the Technical Service Name, the corresponding service will be displayed in the final output.

Select the service and click on the “Add selected service” button.

13

 

The service is successfully added in the caltalog.

14

Copy the standard callback class:

  1. Find the callback class of the standard form.

In our case we will create a callback class as a copy of the standard.

In order to get the standard callback class, we must follow the following path:

SPRO -> SAP Reference IMG -> Cross Application Components -> Output Control.

 

15

 

Double-click on PURCHASE_ORDER.

16

 

The “CL_MM_PUR_PO_OUTPUT_CALLBACK“ is a callback class that invokes the ODATA service.

17

 

2. Copy the standard callback class “CL_MM_PUR_PO_OUTPUT_CALLBACK” to a Z class “ZCL_MM_PUR_PO_OUTPUT_CALLBACK” using the transaction se24.

18

 

    3. Update the “GET_PDF_PARAMETER” method in the Z callback class “ZCL_MM_PUR_PO_OUTPUT_CALLBACK”.

19

 

In line “12”, the standard service name is assigned.

20

 

4. Change the standard service assigned in line 12 by the service we already created in Z (in our example “ZFDP_ PURCHASE_ORDER_AB_SRV”).

21

    5. After activating the custom class, assign the Z class created in SPRO instead of the standard callback class.

 

22

 

6. Next, configure the Z form created at the beginning by the new service.

23

 

Add custom fields in our service:

1. Create a custom entity “Header” to get the email to display it in the first part of the purchase order.

 

24

 

2. Add the “Entity Type Name” and Check the option “create Related Entity Set”.

25

    3. Add the “Email” property to the created entity.

 

26

 

NB: The field “Name “will be user in the form and the “ABAP Field Name” in our ODATA service.

 

4. Save the project.

5. Generate the project, in order to generate the runtime artifacts of the “Header” entity.

 

we must, now, add the association between the entity created and the entity of the main ODATA service, so it can be called automatically.

Adding this association (Cardinality), will decide the use of the “GET_ENTITY” method or “GET_ENTITYSET”.

6. Create an association for the new entity.

27

 

 

Add the association name, primary entity, dependent entity, and cardinality.

 

28

 

The association and the association Set are created.

29

 

7. Generating the project, will automatically generate the models of the new entity created in the “MPC” class (the properties, the entity sets and the associations).

30

 

31

 

8. Add the method to get the data (in our example we will retrieve the Email) in the “DPC_EXT” class.

32

   9. Implement the code to get the “email” ( the field “ad_smtpadr”).

33

 

Our new entity and its method are created, now we have to call the new method.

NB: In a standard service, the call of methods is done at “/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_ENTITY” method, as indicated in the screenshot below.

34

 

10. Redefine the “/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_ENTITY” method in our custom project, so we can add the call to the new method created (Header_get_entity).

35

 

Add the custom field (the Email) created in the Adobe layer.

To modify the form, you can use the LiveCycle Designer locally.

36

 

  1. Download the “.XDP” file of the form using the transaction: FB_XDP_DOWN

 

37

Choose the location.

38

 

 

2. Create the field (in our example, we created a text field) and do the binding.

At the level of the link tab, we make the binding for the created field.The binding is done in this way: $.structure name.property name

39

 

3. Load the processing done in the form, locally in SAP, using the transaction: FB_XDP_UP.

40

 

4. Print the form after the upload.

 

41

 

 

Assigned Tags

      8 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Frank Li
      Frank Li

      Great blog, thanks for sharing. If want to achieve the same functionality as you did in this blog for S4 HANA cloud customer,how to do it? Thanks

      Author's profile photo Seele Yang
      Seele Yang

      Great work you have done, thanks!

      Author's profile photo Abir Cherif
      Abir Cherif
      Blog Post Author

      Thank you !

      Author's profile photo Kumudwini Bheemisetty
      Kumudwini Bheemisetty

      Hello Abir,

      In our current project , we are trying to print the invoice using custom XML based adobe form along with custom odata service. When triggered the output from VF02, the form gets generated but the data is not being populated from the odata service. The service works fine when executed from /IWFND/MAINT_SERVICE. Could you please let us know how else we can bind the service data into the form?

      The Subform has been bound with the Header entity and for the field within the subform, we have direclty used the component of the entity.

      Attached the images here with the comment. Looking forward for your reply.

      subform_binding

      subform_binding

      Regards,

      Kumudwini

      Author's profile photo Abir Cherif
      Abir Cherif
      Blog Post Author

      Hello Kumudwini Bheemisetty,

      To correct the binding, you need to remove the binding indicated in the subform "BillingDocument" and correct the binding indicated in the "invoice" field as follows: $.structure_name.property_name. In your example, it would be $.BillingHeader.BillingDocument.

      1

       

       

      If that doesn't work, could you please provide me with the name of the standard form on which you made the copy? I will try to apply the same scenario in my system to identify the problem.

       

      Best regards,
      Abir.

      Author's profile photo Kumudwini Bheemisetty
      Kumudwini Bheemisetty

      Hi Abir,

      Yes we corrected the binding later posting the comment here and we were able read the data. Thank you for replying.

       

      Regards,

      Kumudwini

      Author's profile photo Abir Cherif
      Abir Cherif
      Blog Post Author

      Hello Kumudwini Bheemisetty,

      Great, you're welcome.

      Best regards,
      Abir.

      Author's profile photo tms47 Singh
      tms47 Singh

      Abir Cherif

      I saw your post and it is helpful. But when similar approach is done to billing invoice, it results in error. Screen shot are attached. When I do for Purchase order then it works fine and every thing is green. Can you help if you also have same issue with billing ? or something I am missing.

      if such error is there and how to proceed with for billing Invoice using fragmented Odata.

      Form - SDBIL_CI_PROF_SRV_DE

      Odata  service - FDP_V3_BD_PROF_SERV

       

      Redefine%20Service

      Redefine Service

      Copy%20All%20and%20Finish

      Copy All and Finish

      Error

      Error